[网络流24题] 圆桌问题 (最大流)
这估计是$24$题里建图最好想的了吧..
源点$S$向每个单位连流量为$r_{i}$的边,每个圆桌向汇点$T$连流量为$c_{i}$的边,每个单位和每个圆桌之间都连一条流量为$1$的边
然后上$Dinic$就行了
最终的方案里,如果一个单位流向一个圆桌的流量为$0$,说明这条边被用上了,即这个单位里有一个人被分配到了这个圆桌
把Dinic模板打错了调了30min
1 #include <vector> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #define N1 505 6 #define M1 50010 7 #define ll long long 8 #define dd double 9 #define inf 0x3f3f3f3f 10 using namespace std; 11 12 int gint() 13 { 14 int ret=0,fh=1;char c=getchar(); 15 while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();} 16 while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();} 17 return ret*fh; 18 } 19 20 int n,m,S,T; 21 struct Edge{ 22 int head[N1],to[M1<<1],nxt[M1<<1],flow[M1<<1],cte; 23 void ae(int u,int v,int F) 24 { 25 cte++; to[cte]=v; flow[cte]=F; 26 nxt[cte]=head[u]; head[u]=cte; 27 } 28 }e; 29 30 int que[N1],hd,tl,cur[N1],dep[N1]; 31 vector<int>pro[N1]; 32 33 int bfs() 34 { 35 int x,j,v; 36 memset(dep,-1,sizeof(dep)); memcpy(cur,e.head,sizeof(cur)); 37 hd=1,tl=0; que[++tl]=S; dep[S]=0; 38 while(hd<=tl) 39 { 40 x=que[hd++]; 41 for(j=e.head[x];j;j=e.nxt[j]) 42 { 43 v=e.to[j]; if(e.flow[j]<=0||dep[v]!=-1) continue; 44 dep[v]=dep[x]+1; que[++tl]=v; 45 } 46 } 47 return dep[T]!=-1; 48 } 49 50 int dfs(int x,int limit) 51 { 52 int j,v,flow,ans=0; 53 if(!limit||x==T) return limit; 54 for(j=cur[x];j;j=e.nxt[j]) 55 { 56 cur[x]=j; v=e.to[j]; 57 if( dep[v]==dep[x]+1 && (flow=dfs(v,min(limit,e.flow[j]))) ) 58 { 59 limit-=flow; ans+=flow; 60 e.flow[j]-=flow; e.flow[j^1]+=flow; 61 if(!limit) break; 62 } 63 } 64 return ans; 65 } 66 67 int Dinic() 68 { 69 int ans=0,flow; 70 bfs(); flow=dfs(S,inf); 71 while(bfs()) 72 { 73 flow=dfs(S,inf); 74 if(!flow) break; 75 ans+=flow; 76 } 77 return ans; 78 } 79 80 int a[N1],b[N1]; 81 82 int main() 83 { 84 scanf("%d%d",&m,&n); 85 int i,j,v,ans; e.cte=1; S=m+n+1,T=m+n+2; 86 for(i=1;i<=m;i++) scanf("%d",&a[i]), e.ae(S,i,a[i]), e.ae(i,S,0); 87 for(i=1;i<=n;i++) scanf("%d",&b[i]), e.ae(m+i,T,b[i]), e.ae(T,m+i,0); 88 for(i=1;i<=m;i++) for(j=m+1;j<=m+n;j++) e.ae(i,j,1), e.ae(j,i,0); 89 ans=Dinic(); 90 for(i=1;i<=m;i++) 91 { 92 for(j=e.head[i],ans=0;j;j=e.nxt[j]){ v=e.to[j]; if(!e.flow[j]) ans++; } 93 if(ans<a[i]){ puts("0"); return 0; } 94 } 95 for(i=1,puts("1");i<=m;puts(""),i++) 96 { 97 for(j=e.head[i];j;j=e.nxt[j]) 98 { 99 v=e.to[j]; 100 if(!e.flow[j]) printf("%d ",v-m); 101 } 102 } 103 return 0; 104 }