PIGS
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 21217 Accepted: 9686
Description
Mirko 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 after another. 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 across the 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.
Input
The 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 and customers 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.
Output
The 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
Source
Croatia OI 2002 Final Exam - First day
WA:
/*
WA的厉害,浪费时间太多了,换了一个矩阵的
不调了
路过大神求指点
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<queue>
using namespace std;
const int MAXN = 1200 ;
#define MAXE MAXN*MAXN*2
#define INF 105000000
int head[MAXN];
struct Edge{ int to,flow,next; }e[MAXE];
int tot,S,T,dep[MAXN],n,m,pig[MAXN];//m--Pig House
int now[MAXN];
void Init(){
tot=0;
memset(head,-1,sizeof head );
}
queue<int> q;
void Insert(int u,int v,int flow){
e[tot].to=v;e[tot].next=head[u];
e[tot].flow=flow;head[u]=tot++;
e[tot].to=u;e[tot].next=head[v];
e[tot].flow=0;head[v]=tot++;
}
bool BFS(int S,int T){
memset(dep,-1,sizeof dep );
dep[S]=0;q.push(S);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];i!=-1;i=e[i].next){
int v=e[i].to,w=e[i].flow;
if(w&&dep[v]==-1){
dep[v]=dep[u]+1;
q.push(v);
}
}
}
return dep[T]!=-1;
}
int DFS(int u,int Flow){
int rt=0;
if(u==T) return Flow;
for(int i=head[u];i!=-1;i=e[i].next){
int v=e[i].to,w=e[i].flow;
if(dep[v]==dep[u]+1&&w){
int x=DFS(v,min(Flow-rt,w));
e[i].flow-=x;e[i^1].flow+=x;
rt+=x;Flow-=x;
}
}
return rt;
}
int Dinic(int S,int T){
int ans=0;
while(BFS(S,T)) ans+=DFS(S,INF);
return ans;
}
int main(){
while(~scanf("%d%d",&m,&n)){
T=n+1;
Init();
for(int i=1;i<=m;i++) scanf("%d",&pig[i]);
memset(now,0,sizeof now );
for(int x,i=1;i<=n;i++){
scanf("%d",&x);//鐚垗鐨勯挜鍖欐暟鐩?
for(int y,j=1;j<=x;j++){
scanf("%d",&y);
if(now[y]) Insert(now[y],i,INF);
else Insert(S,i,pig[y]);
now[y]=i;
}
scanf("%d",&x);//涔扮尓鏁伴噺
Insert(i,T,x);
}
int ans=Dinic(S,T);
printf("%d\n",ans);
}
return 0;
}
AC :
#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int INF = (1<<30);
int pig[1100],flag[1100],res[110][110],dis[110];
int m,n; //m猪圈,n个人
int S = 0,T ;
void init(){
for(int i = 1 ; i <= m ;i++)
scanf("%d",&pig[i]);
memset(res,0,sizeof(res));
memset(flag,0,sizeof(flag));
for(int i = 1 ; i <= n ;i++){
int num;
scanf("%d",&num);
for(int j = 0 ; j < num ;j++){
int room;
scanf("%d",&room);
if(flag[room] == 0) res[S][i] += pig[room];
else res[flag[room]][i] = INF;
flag[room] = i;
}
int xu;
scanf("%d",&xu);
res[i][T] = xu;
}
}
int bfs(){
int tmp;
queue<int>q;
memset(dis,-1,sizeof(dis));
dis[T] = 0;
q.push(T);
while(!q.empty()){
tmp = q.front();
if(tmp == S) return 1;
q.pop();
for(int i = 0 ; i <= T;i++){
if(dis[i] == -1&&res[i][tmp]){
dis[i] = dis[tmp]+1;
q.push(i);
}
}
}
return 0;
}
int dfs(int cur,int c){
if(cur == T) return c;
int tmp = c,flow;
for(int i = 0 ; i <= T ;i++){
if(tmp == 0) break;
if(dis[i]+1 == dis[cur]&&res[cur][i]){
flow = dfs(i,min(res[cur][i],tmp));
res[cur][i] -= flow;
res[i][cur] += flow;
tmp -= flow;
}
}
return c-tmp;
}
void dinic(){
int maxflow = 0;
while(bfs()) maxflow+=dfs(S,INF);
printf("%d\n",maxflow);
}
int main(){
while(~scanf("%d%d",&m,&n)){
T = n+1;
init();
dinic();
}
return 0;
}