• POJ 3155 Hard Life 最大密度子图 最大权闭合图 网络流 二分


    http://poj.org/problem?id=3155

    最大密度子图和最大权闭合图性质很相近(大概可以这么说吧),一个是取最多的边一个是取最多有正贡献的点,而且都是有选一种必须选另一种的限制,一个是选边必须选其两边的点,一个是选正权点必须选其相邻的负权点。

    那么就可以把最大密度子图用最大权闭合图相近的方式写,二分+网络流就可以了,网络流建图方法可以参考我上一篇博客。

    https://blog.csdn.net/power721/article/details/6781518 也就是该博客的第一种做法,不写第二种因为我懒,over。

    顺便我的写法设置的精度单位(随便叫了个名字,领会精神)是1.0/n/n,有自环的话有点不靠谱,1e-4什么的可能逻辑上更合理一点。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<iostream>
     6 #include<queue>
     7 using namespace std;
     8 #define LL long long
     9 const int maxn=2010;
    10 const double minf=1e14;
    11 const double eps=1.0/1e16;
    12 int n,m,s,t;
    13 LL val[maxn]={};
    14 int a[maxn][2]={};
    15 struct nod{
    16     int y,next;double v;
    17 }e[maxn*10]; int head[maxn],tot=1;
    18 queue<int>q; int dep[maxn]={};
    19 int zz[maxn]={},tly=0,vis[maxn]={};
    20 inline void init(int x,int y,double v){
    21     e[++tot].y=y;e[tot].v=v;e[tot].next=head[x];head[x]=tot;
    22 }
    23 bool dfs(){
    24     memset(dep,0,sizeof(dep));
    25     q.push(s);dep[s]=1;
    26     while(!q.empty()){
    27         int x=q.front();q.pop();
    28         for(int i=head[x];i;i=e[i].next){
    29             if(e[i].v>eps&&!dep[e[i].y]){
    30                 dep[e[i].y]=dep[x]+1;
    31                 q.push(e[i].y);
    32             }
    33         }
    34     }
    35     return dep[t];
    36 }
    37 double dfs1(int x,double fc){
    38     if(x==t){
    39         return fc;
    40     }
    41     double he=0,z;
    42     for(int i=head[x];i;i=e[i].next){
    43         if(dep[x]+1==dep[e[i].y]){
    44             z=dfs1(e[i].y,min(fc-he,e[i].v));
    45             he+=z;e[i].v-=z;e[i^1].v+=z;
    46             if(fc-he<eps)break;
    47         }
    48     }
    49     return he;
    50 }
    51 bool check(double v){
    52     memset(head,0,sizeof(head));tot=1;
    53     for(int i=1;i<=m;i++){
    54         init(n+i,a[i][1],minf);init(a[i][1],n+i,0);
    55         init(n+i,a[i][0],minf);init(a[i][0],n+i,0);
    56         init(s,n+i,1.0);init(n+i,s,0);
    57     }
    58     for(int i=1;i<=n;i++){init(i,t,v);init(t,i,0);}
    59     while(dfs())dfs1(s,minf);
    60     for(int i=1;i<=m;i++){
    61         int z=(i-1)*6+1+5;
    62         if(e[z].v>eps){
    63             return 1;
    64         }
    65     }
    66     return 0;
    67 }
    68 void dfs2(int x){
    69     if(x==t)return;
    70     if(x<=n)zz[++tly]=x;
    71     vis[x]=1;
    72     for(int i=head[x];i;i=e[i].next){
    73         if(vis[e[i].y]||e[i].v<eps)continue;
    74         dfs2(e[i].y);
    75     }
    76 }
    77 int main(){
    78     scanf("%d%d",&n,&m);s=n+m+1;t=s+1;
    79     if(n==0){ printf("0
    ");return 0; }
    80     if(m==0){ printf("1
    1
    ");return 0; }
    81     for(int i=1;i<=m;i++){scanf("%d%d",&a[i][0],&a[i][1]);}
    82     double l=0.5,r=m,mid;r=max(r,1.0);
    83     double mi=1.0/(double)n/(double)n;
    84     while(r-l>mi){
    85         mid=(l+r)/2;
    86         if(check(mid))l=mid;
    87         else r=mid;
    88     }
    89     check(l-mi);
    90     dfs2(s);
    91     printf("%d
    ",tly);sort(zz+1,zz+1+tly);
    92     for(int i=1;i<=tly;i++)printf("%d
    ",zz[i]);
    93     return 0;
    94 }
    View Code

  • 相关阅读:
    【干货分享】嵌入式学习路线公开!(书籍推荐+视频推荐+练手项目)
    test
    pytest学习小结
    pytest运行报错 TypeError: attrib() got an unexpected keyword argument 'convert'
    pytest插件下载网址
    python修改文件内容的3种方法详解
    PermissionError: [Errno 13] Permission denied 如何解决
    Pycharm退出pytest模式(run pytest in模式)
    直流电机驱动电路设计-----学习笔记
    2019年全国大学生电子设计竞赛赛题分享与浅析
  • 原文地址:https://www.cnblogs.com/137shoebills/p/9105441.html
Copyright © 2020-2023  润新知