PIGS
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 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 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 最大流,構圖思想:用人當點,因為每個人是按順序的,所以第i個人第一次打開第k個豬圈,第j個人第二次打開第k個豬圈時,相當于第i個人向第j個人增流。 所以,如果第i個人持有第k個豬圈的鑰匙,如果是第一次打開,就從源點引邊向該點,邊權累加豬圈的值(一個人可能持有多個鑰匙,所以要累加),如果不是第一次,那么從上一次那個人引出一條無限大的邊到i點作為增流。每個點到匯點的權值是該人需要的個數,最大流一次就行了。 SAP,時間很好看。 代碼: |
#include<string.h> #include<iostream> #include<queue> #define N 1010 using namespace std; const int maxnode=60000; const int maxedge=320000; const int inf = 1 << 30; int S,T,cnt,n,m; int head[maxnode],gap[maxnode],pre[maxnode],cur[maxnode],dis[maxnode]; struct Edge { int S,t; int next; int w; }st[maxedge]; void init() { memset(head,-1,sizeof(head)); cnt=0; } void AddEdge(int S,int t,int w) { st[cnt].S=S; st[cnt].t=t; st[cnt].w=w; st[cnt].next=head[S]; head[S]=cnt; cnt++; st[cnt].S=t; st[cnt].t=S; st[cnt].w=0; st[cnt].next=head[t]; head[t]=cnt; cnt++; } void bfs() { memset(gap,0,sizeof(gap)); memset(dis,-1,sizeof(dis)); queue<int >Q; Q.push(T); dis[T]=0; gap[0]=1; int k,t; while(!Q.empty()) { k=Q.front(); Q.pop(); for(int i=head[k];i!=-1;i=st[i].next) { t=st[i].t; if(dis[t]==-1&&st[i^1].w>0) { dis[t]=dis[k]+1; gap[dis[t]]++; Q.push(t); } } } } int sap() { int i; for( i=S;i<=T;i++)cur[i]=head[i]; pre[S]=S; int u=S,v; int flow=0; int aug=inf; bool flag; while(dis[S]<=T) { flag=false; for( i=cur[u];i!=-1;i=st[i].next) { v=st[i].t; if(st[i].w>0&&dis[u]==dis[v]+1) { cur[u]=i; flag=true; pre[v]=u; aug=(aug>st[i].w)?st[i].w:aug; u=v; if(v==T) { flow+=aug; for(u=pre[u];v!=S;u=pre[u]) { v=u; st[cur[u]].w-=aug; st[cur[u]^1].w+=aug; } aug=inf; } break; } } if(flag==true)continue; int mint=T; for( i=head[u];i!=-1;i=st[i].next) { v=st[i].t; if(st[i].w>0&&mint>dis[v]) { cur[u]=i; mint=dis[v]; } } gap[dis[u]]--; if(gap[dis[u]]==0)break; gap[dis[u]=mint+1]++; u=pre[u]; if(u==S)aug=inf; } return flow; } int main() { int map[N][N]; int num[N]; int f[N]; while (scanf("%d%d", &m, &n) != EOF) { memset(map, 0, sizeof(map)); memset(f, 0, sizeof(f)); init(); S = 0; T = n + 1; for (int i = 1; i <= m; ++i) scanf("%d", &num[i]); for (int i = 1; i <= n; ++i) { int a, b; scanf("%d", &a); for (int j = 1; j <= a; ++j) { int x; scanf("%d", &x); if (f[x] == 0) { map[S][i] += num[x]; f[x] = i; } else { map[f[x]][i] = inf; f[x] = i; } } scanf("%d", &b); map[i][T] += b; } for (int i = S; i <= T; ++i) for (int j = S; j <= T; ++j) if (map[i][j]) { //printf("%d %d %d\n", i, j, map[i][j]); AddEdge(i, j, map[i][j]); } bfs(); printf("%d\n", sap()); } } /* 4 2 1 2 3 5 3 1 2 3 10 1 4 5 */ |