类似题目(一模一样):http://poj.org/problem?id=1149
我这里以poj1149的PIGS为例,
新建源点s和汇点t,n个顾客作为中间的点,,对于每个顾客,他可以解锁一定的猪圈,枚举这些猪圈,如果当前枚举的猪圈是第一次解锁,由s向该顾客连边,容量为初始时该猪圈中猪的数量;如果猪圈在之前就被解锁了,由最先解锁它的顾客向当前顾客连边,容量为正无穷(因为管理员可以重新分配解锁的猪圈中猪的数量)。最后由每个顾客向汇点连边,容量就是该顾客想买的数量。
#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int N=610,M=4e6+10;
int m,n,s,t,d[N],pre[2510];
int head[N],tot=-1,nxt[M],to[M],cap[M],k[2510];
//tot=-1***********
bool bfs(){
memset(d,0,sizeof(d));
d[s]=1;
queue<int> q;
q.push(s);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];~i;i=nxt[i]){
int v=to[i];
if(!d[v]&&cap[i]){
d[v]=d[u]+1;
if(v==t) return true;
q.push(v);
}
}
}
return false;
}
int dfs(int x,int flow){
if(x==t) return flow;
int rest=flow;
for(int i=head[x];~i&&rest;i=nxt[i]){
int v=to[i];
if(d[v]==d[x]+1&&cap[i]){
int t=dfs(v,min(cap[i],rest));
if(!t) d[v]=0;
cap[i]-=t;
cap[i^1]+=t;
rest-=t;
}
}
return flow-rest;
}
int dinic(){
int maxflow=0;
while(bfs()) maxflow+=dfs(s,INF);
return maxflow;
}
void add(int x,int y,int z){
nxt[++tot]=head[x];
head[x]=tot;
to[tot]=y;
cap[tot]=z;
}
int main(){
int a,b,x;
cin>>m>>n;
s=0;t=n+1;
memset(pre,-1,sizeof(pre));
memset(head,-1,sizeof(head));
for(int i=1;i<=m;i++) cin>>k[i];
for(int i=1;i<=n;i++){
cin>>a;
while(a--){
cin>>x;
if(pre[x]==-1){
add(s,i,k[x]);
add(i,s,0);
}
else{
add(pre[x],i,INF);
add(i,pre[x],0);
}
pre[x]=i;
}
cin>>b;
add(i,t,b);
add(t,i,0);
}
cout<<dinic();
return 0;
}
建好图后套最大流模板就行了(要把模板理解透彻啊,不要像我,成功建好图后套模板出了问题,调试了好久......)