poj 1149 PIGS (最大流)

http://poj.org/problem?id=1149

/*
一开始没很懂题意 ,将 猪圈 和人 一起建了一个图 写了一个最大六模版,可是结果始终 和样例不一样,有读了一遍题 ,题中说 猪圈打开后可以重新调整猪的分配。 这才明白。 1. 对于每个猪圈的第一个顾客,从源点向他连一条边,容量为猪圈里的猪的数量。 2. 对于每个猪圈,如果不是第一个顾客,则上一个打开这个猪圈的顾客向这个顾客连一条边,容量为 +∞。(便于调整猪的重新分配) 3. 每个顾客到汇点连一条边,容量为各个顾客能买的数量。 */ #include<stdio.h> #include<string.h> #define inf 0x7fffffff #define maxn 20000 int min(int x,int y) { if(x<y)return x; else return y; } int n,m,N; int p[maxn],ans; int map[1010][1010],vis[maxn],have[maxn],cost[maxn],pre[maxn]; int bfs() { memset(vis,0,sizeof(vis)); int i,head=0,tail=0; p[head]=0; tail++; vis[0]=1; while(head!=tail) { int k=p[head]; if(k==m)return 1; for(i=0;i<=m;i++) { if(!vis[i]&&map[k][i]) { vis[i]=1; pre[i]=k; p[tail++]=i; if(i==m)return 1; if(tail==maxn)tail=0; } } head++; if(head==maxn)head=0; } return 0; } void EK() { int i,sum=inf; for(i=m;i!=0;i=pre[i]) { sum=min(sum,map[pre[i]][i]); } for(i=m;i!=0;i=pre[i]) { map[pre[i]][i]-=sum; map[i][pre[i]]+=sum; } ans+=sum; } int main() { int i,l,a,k; while(scanf("%d%d",&n,&m)!=EOF) { for(i=1;i<=n;i++)scanf("%d",&have[i]); memset(map,0,sizeof(map)); memset(pre,0,sizeof(pre)); for(l=1;l<=m;l++) { scanf("%d",&a); while(a--) { scanf("%d",&k); if(pre[k]==0) map[0][l]+=have[k]; else map[pre[k]][l]=inf;//为什么连边 ,因为打开后可以调整猪分配 而且 人来是有顺序的。 pre[k]=l; } scanf("%d",&map[l][m+1]); } m++; ans=0; while(bfs())EK(); printf("%d\n",ans); } }
posted @ 2012-05-04 20:58  Szz  阅读(205)  评论(0编辑  收藏  举报