您的位置:首页 > 其它

[最大流] poj 1149 pigs

2012-08-26 18:38 387 查看
/**
[最大流] poj 1149 pigs
关键在于构图,
每个顾客分别用一个节点来表示。
对于每个猪圈的第一个顾客,从源点向他连一条边,容量就是该猪圈里的猪的初始数量。
如果从源点到一名顾客有多条边,则可以把它们合并成一条,容量相加。
对于每个猪圈,假设有 n 个顾客打开过它,
则对所有整数 i ∈ [1, n),从该猪圈的第 i 个顾客向第 i + 1 个顾客连一条边,容量为 +∞。
从各个顾客到汇点各有一条边,容量是各个顾客能买的数量上限。

last[i] 记录i个猪圈上次被谁打开
*/
#include <stdio.h>
#include <string.h>

#define typec int
#define N 100004
#define E 1100001
// type of cost
const typec inf = 1000000000;
// max of cost
struct edge { int x, y, nxt; typec c; } bf[E];
int ne, head[E], cur[E], ps[E], dep[E];
void addedge(int x, int y, typec c)
{
// add an arc(x -> y, c); vertex: 0 ~ n-1;
bf[ne].x = x; bf[ne].y = y; bf[ne].c = c;
bf[ne].nxt = head[x]; head[x] = ne++;
bf[ne].x = y; bf[ne].y = x; bf[ne].c = 0;
bf[ne].nxt = head[y]; head[y] = ne++;
}
typec flow(int n, int s, int t)
{
typec tr, res = 0;
int i, j, k, f, r, top;
while (1) {
memset(dep, -1, n * sizeof(int));
for (f = dep[ps[0] = s] = 0, r = 1; f != r; )
for (i = ps[f++], j = head[i]; j; j = bf[j].nxt)
if(bf[j].c && -1 == dep[k = bf[j].y]){
dep[k] = dep[i] + 1;ps[r++] = k;
if(k == t)
{
f = r;
break;
}
}
if(-1 == dep[t])
break;

memcpy(cur,head,n * sizeof(int));
for(i = s,top = 0;;){
if(i == t){
for(k = 0,tr = inf; k < top; ++k)
if(bf[ps[k]].c < tr)
tr = bf[ps[f = k]].c;
for(k = 0; k < top; ++k)
bf[ps[k]].c -= tr,bf[ps[k]^1].c += tr;
res += tr;
i = bf[ps[top = f]].x;
}
for(j = cur[i]; cur[i]; j = cur[i] = bf[cur[i]].nxt)
if(bf[j].c && dep[i] + 1 == dep[bf[j].y])
break;
if(cur[i]){
ps[top++] = cur[i];
i = bf[cur[i]].y;
}
else{
if(0 == top)
break;
dep[i] = -1;
i = bf[ps[--top]].x;
}
}
}
return res;
}

int main()
{
// freopen("1.in","r",stdin);
int s = 0,t,m,n,i,j,last
,pig
,a,k;
while(scanf("%d%d",&m,&n) != EOF)
{
memset(last,0,sizeof(last));
memset(head,0,sizeof(head));
ne = 2;
t = n + 1;
for(i = 1; i <= m; ++i)
scanf("%d",pig + i);
for(i = 1; i <= n; ++i)
{
scanf("%d",&a);
while(a--)
{
scanf("%d",&k);
if(last[k] == 0)
addedge(s,i,pig[k]);
else
addedge(last[k],i,inf);
last[k] = i;
}
scanf("%d\n",&k);
addedge(i,t,k);
}
printf("%d\n",flow(t+1,s,t));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: