poj1149 2010.3.5
Poj 1149 Pigs
【关键字】
最大流
【摘要】
一些顾客要到好多个猪圈里去买猪,每个人有一些猪圈的钥匙,求最多可以卖出多少猪。
【正文】
1、题目描述
PIGS
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 6439 Accepted: 2761
Description
Mirko works on a pig farm that consists ofM locked pig-houses and Mirko can't unlock any pighouse because he doesn't havethe keys. Customers come to the farm one after another. Each of them has keysto some pig-houses and wants to buy a certain number of pigs.
All data concerning customers planning tovisit the farm on that particular day are available to Mirko early in themorning so that he can make a sales-plan in order to maximize the number ofpigs sold.
More precisely, the procedure is asfollowing: the customer arives, 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 across the unlockedpig-houses.
An unlimited number of pigs can be placedin every pig-house.
Write a program that will find the maximumnumber of pigs that he can sell on that day.
Input
The first line of input contains twointegers M and N, 1 <= M <= 1000, 1 <= N <= 100, number of pighousesand number of customers. Pig houses are numbered from 1 to M and customers arenumbered from 1 to N.
The next line contains M integeres, foreach pig-house initial number of pigs. The number of pigs in each pig-house isgreater or equal to 0 and less or equal to 1000.
The next N lines contains records about thecustomers in the following form ( record about the i-th customer is written inthe (i+2)-th line):
A K1 K2 ... KA B It means that thiscustomer has key to the pig-houses marked with the numbers K1, K2, ..., KA (sorted nondecreasingly ) and that he wantsto buy B pigs. Numbers A and B can be equal to 0.
Output
The first and only line of the outputshould contain the number of sold pigs.
SampleInput
3 3
3 1 10
2 1 2 2
2 1 3 3
1 2 6
SampleOutput
7
Source
Croatia OI 2002 Final Exam - First day
2、算法分析
圈为顶点。新设两个顶点,一个s,一个t,当第一个顾客有个一个猪圈的钥匙时,就有一条从s到该顾客的边,容量为猪圈中猪的数量,以后另外有顾客有这个猪圈的钥匙是,则有一条从前一个顾客到这个顾客的边,容量为无穷大,同时每个顾客都有到t的边,容量为顾客的需求量。求最大流,使用Relabel-To-Front算法,具体算法:最大流问题
调试问题:
忘记合并重边
感慨:
1. 图的问题,题目提供的数据,必然是一个用来当节点,一个用来建边的
2. 图的题目,图的建立很重要。
3、源码
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define MAXN 1000+10
#define INF 1000000000
int flow[MAXN][MAXN],cap[MAXN][MAXN],a[MAXN],p[MAXN];
int n,s,t,m,f,nmax;
int flag[MAXN];
int pig[MAXN];
void edmondskarp();
void init();
void edmondskarp()
{
queue<int> q;
memset(flow,0,sizeof(flow));
f=0;
for(;;)
{
memset(a,0,sizeof(a));
a[s]=INF;
q.push(s);
while (!q.empty())
{
int u=q.front();
q.pop();
for(int v=1;v<=n;v++)
if (!a[v]&&cap[u][v]>flow[u][v])
{
p[v]=u;
q.push(v);
if (a[u]<cap[u][v]-flow[u][v])
a[v]=a[u];
else a[v]=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];
}
f+=a[t];
}
}
void init()
{
int i,j,t1,t2;
for(i=1;i<=m;i++)
scanf("%d",&pig[i]);
for(i=1;i<=n-2;i++)
{
scanf("%d",&t1);
for(j=1;j<=t1;j++)
{
scanf("%d",&t2);
if (flag[t2])
{
cap[flag[t2]][i]=INF;
flag[t2]=i;
}
else
{
flag[t2]=i;
cap[s][i]+=pig[t2];//少了这个加号,就回wa的很惨
}
}
scanf("%d",&cap[i][t]);
}
}
int main()
{
scanf("%d %d",&m,&n);
memset(cap,0,sizeof(cap));
memset(flag,0,sizeof(flag));
n++;
s=n;
n++;
t=n;
init();
edmondskarp();
printf("%d\n",f);
return 0;
}