1. 程式人生 > >[網絡流24題] 圓桌問題 (最大流)

[網絡流24題] 圓桌問題 (最大流)

sizeof ble har 一個 lan double ace cor cte

洛谷傳送門 LOJ傳送門

這估計是$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 }

[網絡流24題] 圓桌問題 (最大流)