网络流24题之圆桌问题
对于每个单位连源点到其的边,流量为单位人数
每个单位对每个桌子连边,流量为1
每个桌子对终点连边,流量为桌子人数
判断最大匹配是不是为总人数
By:大奕哥
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=20005; 4 int head[N],d[N],a[N],c[N]; 5 int n,m,cnt=-1,s,t,sum; 6 struct node{ 7 int to,nex,w; 8 }e[1000005]; 9 void add(int x,int y,int w) 10 { 11 e[++cnt].to=y;e[cnt].nex=head[x];head[x]=cnt;e[cnt].w=w; 12 e[++cnt].to=x;e[cnt].nex=head[y];head[y]=cnt;e[cnt].w=0; 13 } 14 queue<int>q; 15 bool bfs(int x,int y) 16 { 17 memset(d,-1,sizeof(d)); 18 d[x]=0;q.push(x); 19 while(!q.empty()) 20 { 21 int x=q.front();q.pop(); 22 for(int i=head[x];i!=-1;i=e[i].nex) 23 { 24 int y=e[i].to; 25 if(d[y]!=-1||!e[i].w)continue; 26 d[y]=d[x]+1;q.push(y); 27 } 28 } 29 return d[y]!=-1; 30 } 31 int dfs(int x,int w,int yy) 32 { 33 if(x==yy||!w)return w; 34 int s=0; 35 for(int i=head[x];i!=-1;i=e[i].nex) 36 { 37 int y=e[i].to; 38 if(!e[i].w||d[y]!=d[x]+1)continue; 39 int flow=dfs(y,min(w-s,e[i].w),yy); 40 if(!flow){ 41 d[y]=-1;continue; 42 } 43 e[i].w-=flow;e[i^1].w+=flow;s+=flow; 44 if(s==w)return s; 45 } 46 return s; 47 } 48 int dinic() 49 { 50 int ans=0; 51 while(bfs(s,t)) 52 { 53 ans+=dfs(s,1e9,t); 54 } 55 return ans; 56 } 57 int main() 58 { 59 scanf("%d%d",&m,&n); 60 s=0;t=n+m+10;memset(head,-1,sizeof(head)); 61 for(int i=1;i<=m;++i) 62 { 63 scanf("%d",&a[i]); 64 add(s,i,a[i]);sum+=a[i]; 65 for(int j=1;j<=n;++j) 66 add(i,j+m,1); 67 } 68 for(int i=1;i<=n;++i) 69 { 70 scanf("%d",&c[i]); 71 add(i+m,t,c[i]); 72 } 73 int ans=dinic(); 74 if(ans!=sum) 75 { 76 printf("0");return 0; 77 } 78 puts("1"); 79 for(int i=1;i<=m;++i) 80 { 81 for(int j=head[i];j!=-1;j=e[j].nex) 82 { 83 if(e[j].w)continue; 84 printf("%d ",e[j].to-m); 85 } 86 printf("\n"); 87 } 88 return 0; 89 }
生命中真正重要的不是你遭遇了什么,而是你记住了哪些事,又是如何铭记的。