洛谷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 }

建好图后套最大流模板就行了(要把模板理解透彻啊,不要像我,成功建好图后套模板出了问题,调试了好久......)

posted @ 2022-04-04 15:03  YHXo  阅读(20)  评论(0编辑  收藏  举报