It is easy to think of the source point to the type has a sticker edge, the capacity of Bob at the beginning of the quantity, and then the sticker to the meeting point edge, the capacity of 1.
The next part is the exchange of the edge. Note that the swap takes place one at a time.
Swap, is for both stickers, only occurs in one sticker a friend has a quantity of 0, while another friend has more than 1.
So the map, for each friend, if the sticker number is 0, then this sticker to this friend with a capacity of 1 side; If the number x is greater than 1, the friend over there has a capacity of x-1 on the side of the sticker.
1#include <cstdio>2#include <cstring>3#include <queue>4#include <algorithm>5 using namespacestd;6 #defineINF (1<<30)7 #defineMAXN 558 #defineMAXM 55*55*29 Ten structedge{ One intV,cap,flow,next; A }EDGE[MAXM]; - intVs,vt,ne,nv; - intHEAD[MAXN]; the - voidAddedge (intUintVintcap) { -Edge[ne].v=v; Edge[ne].cap=cap; edge[ne].flow=0; -Edge[ne].next=head[u]; head[u]=ne++; +Edge[ne].v=u; edge[ne].cap=0; edge[ne].flow=0; -EDGE[NE].NEXT=HEAD[V]; head[v]=ne++; + } A at intLEVEL[MAXN]; - intGAP[MAXN]; - voidBFs () { -memset (level,-1,sizeof(level)); -Memset (Gap,0,sizeof(GAP)); -level[vt]=0; ingap[level[vt]]++; -queue<int>que; to Que.push (VT); + while(!Que.empty ()) { - intu=Que.front (); Que.pop (); the for(intI=head[u]; i!=-1; I=Edge[i].next) { * intv=edge[i].v; $ if(level[v]!=-1)Continue;Panax Notoginsenglevel[v]=level[u]+1; -gap[level[v]]++; the Que.push (v); + } A } the } + - intPRE[MAXN]; $ intCUR[MAXN]; $ intIsap () { - BFS (); -memset (pre,-1,sizeof(pre)); thememcpy (Cur,head,sizeof(head)); - intu=pre[vs]=vs,flow=0, aug=INF;Wuyigap[0]=NV; the while(level[vs]<NV) { - BOOLflag=false; Wu for(int&i=cur[u]; i!=-1; I=Edge[i].next) { - intv=edge[i].v; About if(Edge[i].cap!=edge[i].flow && level[u]==level[v]+1){ $flag=true; -pre[v]=u; -u=v; - //aug= (Aug==-1?edge[i].cap:min (Aug,edge[i].cap)); AAug=min (aug,edge[i].cap-edge[i].flow); + if(v==VT) { theflow+=; - for(u=pre[v]; V!=vs; v=u,u=Pre[u]) { $edge[cur[u]].flow+=; theedge[cur[u]^1].flow-=; the } the //Aug=-1; theaug=INF; - } in Break; the } the } About if(flag)Continue; the intMinlevel=NV; the for(intI=head[u]; i!=-1; I=Edge[i].next) { the intv=edge[i].v; + if(Edge[i].cap!=edge[i].flow && level[v]<minlevel) { -Minlevel=Level[v]; thecur[u]=i;Bayi } the } the if(--gap[level[u]]==0) Break; -level[u]=minlevel+1; -gap[level[u]]++; theu=Pre[u]; the } the returnflow; the } - the intMain () { the intt,n,m,a,b; thescanf"%d",&t);94 for(intCse=1; cse<=t;++CSE) { thescanf"%d%d",&n,&m); thememset (head,-1,sizeof(head)); thevs=0; vt=n+m+1; nv=vt+1; Ne=0;98 Aboutscanf"%d",&a); - intcnt[ -]={0};101 while(a--){102scanf"%d",&b);103++Cnt[b];104 } the for(intI=1; i<=m;++i) {106 if(cnt[i]==0)Continue;107 Addedge (Vs,i,cnt[i]);108 }109 the for(intI=1; i<=m;++i) Addedge (I,VT,1);111 the for(intI=2; i<=n;++i) {113scanf"%d",&a); the intcnt[ -]={0}; the while(a--){ thescanf"%d",&b);117++Cnt[b];118 }119 for(intj=1; j<=m;++j) { - if(cnt[j]>=2){121Addedge (i+m,j,cnt[j]-1);122}Else if(cnt[j]==0){123Addedge (J,i+m,1);124 } the }126 }127 -printf"Case #%d:%d\n", Cse,isap ());129 } the return 0;131}
UVa10779 collectors problem (maximum flow)