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 }