//11166606 c00h00g 1149 Accepted 696K 47MS G++ 1819B 2013-01-09 12:03:48
//将顾客看成顶点,构造网络流
//废话不多说,参看大牛解释 http://wenku.baidu.com/view/0ad00abec77da26925c5b01c.html
#include<stdio.h>
#include<stdlib.h>
#include<queue>
#include<string.h>
using namespace std;
#define INF 0x7FFFFFFF
int cap[105][105];//容量
int flow[105][105];//流量
int vis[1005];//记录第一次访问猪圈的顾客编号
int a[105];//用于记录边的最小值
int p[105];//记录父亲节点
int pig[1005];//记录猪圈的容量
int M,N;
int main(){
while(scanf("%d%d",&M,&N)!=EOF){
memset(cap,0,sizeof(cap));
memset(flow,0,sizeof(flow));
memset(vis,0,sizeof(vis));
for(int i=1;i<=M;i++)
scanf("%d",&pig[i]);
int num,pig_id,buy;
//对于每一个顾客
for(int i=1;i<=N;i++){
scanf("%d",&num);
for(int j=0;j<num;j++){
scanf("%d",&pig_id);
//访问该猪圈的第一名顾客
if(vis[pig_id]==0){
vis[pig_id]=i;
cap[0][i]+=pig[pig_id];
}else{
cap[vis[pig_id]][i]=INF;
}
}
scanf("%d",&buy);
cap[i][N+1]=buy;
}
int res=0,s,t;
queue<int> q;
s=0,t=N+1;
for(;;){
memset(a,0,sizeof(a));
a[s]=INF;
q.push(s);
while(!q.empty()){
int u=q.front();q.pop();
for(int v=0;v<=N+1;v++)
if(!a[v]&&cap[u][v]>flow[u][v]){
p[v]=u;q.push(v);
a[v]=((a[u]<(cap[u][v]-flow[u][v]))?a[u]:(cap[u][v]-flow[u][v]));
}
}
if(a[t]==0)
break;
for(int u=t;u!=s;u=p[u]){
flow[p[u]][u]+=a[t];
flow[u][p[u]]-=a[t];
}
res+=a[t];
}
printf("%d\n",res);
}
return 0;
}
POJ 1149 最大流 PIGS
最新推荐文章于 2019-12-18 20:07:00 发布