POJ3155 Hard Life

https://vjudge.net/problem/POJ-3155

最大密度子图模板,在求max(|E|-g|V|)采用了Maxflow(n,n+m)的建图方法。

精度上,要求密度的精度高于最小割的精度。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cstdlib>
  4 #include<algorithm>
  5 //#include<iostream>
  6 using namespace std;
  7 #define LL long long
  8 
  9 int n,m;
 10 #define maxn 111
 11 #define maxm 1011*4+maxn*4
 12 #define eps 1e-5
 13 struct NetEdge{int to,next; double cap,flow;};
 14 struct Net
 15 {
 16     int n,le,s,t,first[maxn],dis[maxn],cur[maxn],que[maxn],head,tail; NetEdge edge[maxm]; bool vis[maxn];
 17     void clear(int N) {n=N; le=2; memset(first,0,sizeof(first));}
 18     void in(int x,int y,double c) {NetEdge &e=edge[le]; e.to=y; e.cap=c; e.flow=0; e.next=first[x]; first[x]=le++;}
 19     void insert(int x,int y,double c) {in(x,y,c); in(y,x,0);}
 20     bool bfs()
 21     {
 22         memset(dis,0,sizeof(dis));
 23         head=0; tail=1; que[0]=s; dis[s]=1;
 24         while (head!=tail)
 25         {
 26             int x=que[head++];
 27             for (int i=first[x];i;i=edge[i].next)
 28             {
 29                 NetEdge &e=edge[i]; if (dis[e.to] || e.cap-e.flow<eps) continue;
 30                 dis[e.to]=dis[x]+1; que[tail++]=e.to;
 31             }
 32         }
 33         return dis[t]>0;
 34     }
 35     double dfs(int x,double a)
 36     {
 37         if (x==t || a<eps) return a;
 38         double flow=0,f;
 39         for (int &i=cur[x];i;i=edge[i].next)
 40         {
 41             NetEdge &e=edge[i];
 42             if (dis[e.to]==dis[x]+1 && (f=dfs(e.to,min(a,e.cap-e.flow)))>eps)
 43             {
 44                 e.flow+=f;
 45                 flow+=f;
 46                 edge[i^1].flow-=f;
 47                 a-=f;
 48                 if (a<eps) break;
 49             }
 50         }
 51         return flow;
 52     }
 53     double Dinic(int S,int T)
 54     {
 55         s=S; t=T;
 56         double flow=0;
 57         while (bfs())
 58         {
 59             for (int i=1;i<=n;i++) cur[i]=first[i];
 60             flow+=dfs(s,0x3f3f3f3f);
 61         }
 62         return flow;
 63     }
 64     void dfs2(int x)
 65     {
 66         vis[x]=1;
 67         for (int i=first[x];i;i=edge[i].next)
 68             if (!vis[edge[i].to] && edge[i^1].cap-edge[i^1].flow>eps) dfs2(edge[i].to);
 69     }
 70 }g,g2;
 71 
 72 int du[maxn],lans,ans[maxn];
 73 int main()
 74 {
 75     scanf("%d%d",&n,&m);
 76     g.clear(n+2);
 77     memset(du,0,sizeof(du));
 78     for (int i=1,x,y;i<=m;i++)
 79     {
 80         scanf("%d%d",&x,&y);
 81         g.insert(x,y,1); g.insert(y,x,1);
 82         du[x]++; du[y]++;
 83     }
 84     for (int i=1;i<=n;i++) g.insert(n+1,i,m);
 85     double L=0,R=(n-1)>>1;
 86     while (R-L>1e-7)
 87     {
 88         double mid=(L+R)/2.;
 89         g2=g;
 90         for (int i=1;i<=n;i++) g2.insert(i,n+2,m+2*mid-du[i]);
 91         if (m*n-g2.Dinic(n+1,n+2)>eps) L=mid+1e-7;
 92         else R=mid;
 93     }
 94     
 95     g2=g;
 96     for (int i=1;i<=n;i++) g2.insert(i,n+2,m+2*L-du[i]);
 97     g2.Dinic(n+1,n+2);
 98     memset(g2.vis,0,sizeof(g2.vis));
 99     g2.dfs2(n+2);
100     lans=0;
101     for (int i=1;i<=n;i++) if (!g2.vis[i]) ans[++lans]=i;
102     if (lans==0) ans[++lans]=1;
103     printf("%d\n",lans);
104     for (int i=1;i<=lans;i++) printf("%d\n",ans[i]);
105     return 0;
106 }
View Code

 

posted @ 2020-02-05 11:37  Blue233333  阅读(111)  评论(0编辑  收藏  举报