您的位置:首页 > 其它

POJ 1149 PIGS (最大流)

2013-05-04 20:54 435 查看
PIGS
Time Limit: 1000MSMemory Limit: 10000K
Total Submissions: 13538Accepted: 5973
DescriptionMirko works on a pig farm that consists of M locked pig-houses and Mirko can't unlock any pighouse because he doesn't have the keys. Customers come to the farm one afteranother. Each of them has keys to some pig-houses and wants to buy a certain number of pigs.All data concerning customers planning to visit the farm on that particular day are available to Mirko early in the morning so that he can make a sales-plan in order to maximize the number of pigs sold.More precisely, the procedure is as following: the customer arrives, opens all pig-houses to which he has the key, Mirko sells a certain number of pigs from all the unlocked pig-houses to him, and, if Mirko wants, he can redistribute the remaining pigs acrossthe unlocked pig-houses.An unlimited number of pigs can be placed in every pig-house.Write a program that will find the maximum number of pigs that he can sell on that day.InputThe first line of input contains two integers M and N, 1 <= M <= 1000, 1 <= N <= 100, number of pighouses and number of customers. Pig houses are numbered from 1 to M andcustomers are numbered from 1 to N.The next line contains M integeres, for each pig-house initial number of pigs. The number of pigs in each pig-house is greater or equal to 0 and less or equal to 1000.The next N lines contains records about the customers in the following form ( record about the i-th customer is written in the (i+2)-th line):A K1 K2 ... KA B It means that this customer has key to the pig-houses marked with the numbers K1, K2, ..., KA (sorted nondecreasingly ) and that he wants to buy B pigs. Numbers A and B can be equal to 0.OutputThe first and only line of the output should contain the number of sold pigs.Sample Input
3 3
3 1 10
2 1 2 2
2 1 3 3
1 2 6
Sample Output
7
 
经典构图题。首先源点和每个人连边,权值为人的购买量;其次人与猪圈连边,容量为无穷大;然后猪圈与汇点连边,容量为猪圈内猪的数量;最后对于当前人,如果他能开的猪圈之前有人开过,那么将这人与之前能开这个猪圈的人连边,权值为无穷大。最后直接跑ISAP。
 
//340 KB	0 ms
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define SIZE 1111
#define inf 0x7fffffff

using namespace std;

struct node
{
int to,val,next;
}edge[SIZE*111];

int M,N,sc,sk,pt;
int head[SIZE],idx;
bool cnt[111][SIZE];
int dis[SIZE],gap[SIZE];

void addnode(int from,int to,int val)
{
edge[idx].to = to;
edge[idx].val = val;
edge[idx].next = head[from];
head[from] =  idx ++;
edge[idx].to = from;
edge[idx].val = 0;
edge[idx].next = head[to];
head[to] = idx ++;
}

int dfs(int cur,int cval)
{
if(cur == sk)
return cval;
int mindis = pt - 1, tval = cval;
for(int i=head[cur]; i!=-1; i=edge[i].next)
{
int to = edge[i].to;
if(edge[i].val > 0)
{
if(dis[to] + 1 == dis[cur])
{
int val = dfs(to,min(edge[i].val,tval));
tval -= val;
edge[i].val -= val;
edge[i^1].val += val;
if(dis[sc] >= pt)
return cval-tval;
if(tval == 0)
break;
}
if(dis[to] < mindis)
mindis = dis[to];
}
}
if(cval == tval)
{
--gap[dis[cur]];
if(!gap[dis[cur]])
dis[sc] = pt;
dis[cur] = mindis + 1;
++gap[dis[cur]];
}
return cval-tval;
}

void sap()
{
memset(dis,0,sizeof(dis));
memset(gap,0,sizeof(gap));
int ret = 0;
gap[sc] = pt;
while(dis[sc] < pt)
ret += dfs(sc,inf);
printf("%d\n",ret);
}

void read()
{
idx = 0;
sc = 0, sk = N+M+1, pt = sk+1;
memset(head,-1,sizeof(head));
memset(cnt,0,sizeof(cnt));
int A,B,t;
for(int i=1; i<=M; i++)
{
scanf("%d",&t);
addnode(N+i,sk,t);
}
for(int i=1; i<=N; i++)
{
scanf("%d",&A);
for(int j=1; j<=A; j++)
{
scanf("%d",&t);
cnt[i][t] = true;
for(int k=i-1; k>=1; k--)
{
if(cnt[k][t])
addnode(i,k,inf);
}
addnode(i,N+t,inf);
}
scanf("%d",&B);
addnode(sc,i,B);
}
}

int main()
{
while(~scanf("%d%d",&M,&N))
{
read();
sap();
}
return 0;
}
 

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: