洛谷P4638 SHOI2011 银行 ( 最大流)
类似题目(一模一样):http://poj.org/problem?id=1149
我这里以poj1149的PIGS为例,
新建源点s和汇点t,n个顾客作为中间的点,,对于每个顾客,他可以解锁一定的猪圈,枚举这些猪圈,如果当前枚举的猪圈是第一次解锁,由s向该顾客连边,容量为初始时该猪圈中猪的数量;如果猪圈在之前就被解锁了,由最先解锁它的顾客向当前顾客连边,容量为正无穷(因为管理员可以重新分配解锁的猪圈中猪的数量)。最后由每个顾客向汇点连边,容量就是该顾客想买的数量。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int INF=0x3f3f3f3f; 4 const int N=610,M=4e6+10; 5 int m,n,s,t,d[N],pre[2510]; 6 int head[N],tot=-1,nxt[M],to[M],cap[M],k[2510]; 7 //tot=-1*********** 8 bool bfs(){ 9 memset(d,0,sizeof(d)); 10 d[s]=1; 11 queue<int> q; 12 q.push(s); 13 while(!q.empty()){ 14 int u=q.front();q.pop(); 15 for(int i=head[u];~i;i=nxt[i]){ 16 int v=to[i]; 17 if(!d[v]&&cap[i]){ 18 d[v]=d[u]+1; 19 if(v==t) return true; 20 q.push(v); 21 } 22 } 23 } 24 return false; 25 } 26 27 int dfs(int x,int flow){ 28 if(x==t) return flow; 29 int rest=flow; 30 for(int i=head[x];~i&&rest;i=nxt[i]){ 31 int v=to[i]; 32 if(d[v]==d[x]+1&&cap[i]){ 33 int t=dfs(v,min(cap[i],rest)); 34 if(!t) d[v]=0; 35 cap[i]-=t; 36 cap[i^1]+=t; 37 rest-=t; 38 } 39 } 40 return flow-rest; 41 } 42 43 int dinic(){ 44 int maxflow=0; 45 while(bfs()) maxflow+=dfs(s,INF); 46 return maxflow; 47 } 48 49 void add(int x,int y,int z){ 50 nxt[++tot]=head[x]; 51 head[x]=tot; 52 to[tot]=y; 53 cap[tot]=z; 54 } 55 56 int main(){ 57 int a,b,x; 58 cin>>m>>n; 59 s=0;t=n+1; 60 memset(pre,-1,sizeof(pre)); 61 memset(head,-1,sizeof(head)); 62 for(int i=1;i<=m;i++) cin>>k[i]; 63 for(int i=1;i<=n;i++){ 64 cin>>a; 65 while(a--){ 66 cin>>x; 67 if(pre[x]==-1){ 68 add(s,i,k[x]); 69 add(i,s,0); 70 } 71 else{ 72 add(pre[x],i,INF); 73 add(i,pre[x],0); 74 } 75 pre[x]=i; 76 } 77 cin>>b; 78 add(i,t,b); 79 add(t,i,0); 80 } 81 cout<<dinic(); 82 return 0; 83 }
建好图后套最大流模板就行了(要把模板理解透彻啊,不要像我,成功建好图后套模板出了问题,调试了好久......)