POJ1149 PIGS[dinic()最大流]

PIGS
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 12578   Accepted: 5560

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

 
 
 
 
这题主要是构图比较难,这题以人为节点,如果有公共节点的人就作为前驱

 
 
code:
  1 #include<iostream>
  2 using namespace std;
  3 
  4 #define MAXN 110
  5 #define inf 0x7fffffff
  6 
  7 int n,m;
  8 int cnt[1010];
  9 int pre[1010];
 10 int dis[1010];
 11 int edgenum;
 12 
 13 typedef struct edge
 14 {
 15     int from,to,cap;
 16     int next;
 17 }Edge;
 18 Edge edge[MAXN*10];
 19 int head[MAXN];
 20 
 21 void addedge(int a,int b,int c)
 22 {
 23     edge[edgenum].from=a,edge[edgenum].to=b,edge[edgenum].cap=c,edge[edgenum].next=head[a],head[a]=edgenum++;
 24     edge[edgenum].from=b,edge[edgenum].to=a,edge[edgenum].cap=0,edge[edgenum].next=head[b],head[b]=edgenum++;
 25 }
 26 
 27 int dinic(int st,int et)
 28 {
 29     int sta[1010];
 30     int que[1010];
 31     int ans=0;
 32     while(true)
 33     {
 34         memset(dis,-1,sizeof(dis));
 35         int front=0,tail=0;
 36         int u,v;
 37         dis[st]=0;
 38         que[tail++]=st;
 39         while(front<tail)
 40         {
 41             v=que[front++];
 42             for(int i=head[v];i!=-1;i=edge[i].next)
 43             {
 44                 u=edge[i].to;
 45                 if(dis[u]==-1&&edge[i].cap>0)
 46                 {
 47                     dis[u]=dis[v]+1;
 48                     que[tail++]=u;
 49                     if(u==et)
 50                     {
 51                         front=tail;
 52                         break;
 53                     }
 54                 }
 55             }
 56         }
 57         if(dis[et]==-1)
 58             break;
 59         int t=0;
 60         int s=st;
 61         while(true)
 62         {
 63             if(s!=et)
 64             {
 65                 int i;
 66                 for(i=head[s];i!=-1;i=edge[i].next)
 67                     if(edge[i].cap>0&&dis[edge[i].from]+1==dis[edge[i].to])
 68                         break;
 69                 if(i!=-1)
 70                 {
 71                     sta[t++]=i;
 72                     s=edge[i].to;
 73                 }
 74                 else
 75                 {
 76                     if(t==0)
 77                         break;
 78                     dis[edge[sta[--t]].to]=-1;
 79                     s=edge[sta[t]].from;
 80                 }
 81             }
 82             else
 83             {
 84                 int mindis=inf;
 85                 int tag;
 86                 for(int i=0;i<t;i++)
 87                     if(mindis>edge[sta[i]].cap)
 88                     {
 89                         mindis=edge[sta[i]].cap;
 90                         tag=i;
 91                     }
 92                 ans+=mindis;
 93                 for(int i=0;i<t;i++)
 94                 {
 95                     edge[sta[i]].cap-=mindis;
 96                     edge[sta[i]^1].cap+=mindis;
 97                 }
 98                 s=edge[sta[tag]].from;
 99                 t=tag;
100             }
101         }
102     }
103     return ans;
104 }
105 
106 int main()
107 {
108     int i,j;
109     int vst[1010];
110     edgenum=0;
111     memset(vst,0,sizeof(vst));
112     memset(head,-1,sizeof(head));
113     memset(pre,0,sizeof(pre));
114     scanf("%d%d",&m,&n);                   //m:猪栏数量;n:人数
115     int s=0,t=n+1;
116     for(int i=1;i<=m;i++)
117         scanf("%d",&cnt[i]);
118     for(i=1;i<=n;i++)
119     {
120         int count,a,cap;
121         int ans=0;
122         scanf("%d",&count);
123         for(j=0;j<count;j++)
124         {
125             scanf("%d",&a);
126             if(!vst[a])
127             {
128                 ans+=cnt[a];
129                 vst[a]=true;
130                 pre[a]=i;
131             }
132             else
133             {
134                 addedge(pre[a],i,inf);
135             }            
136         }
137         if(ans)
138             addedge(s,i,ans);
139         scanf("%d",&cap);
140         addedge(i,t,cap);
141     }
142     printf("%d\n",dinic(s,t));
143     return 0;
144 }
原文地址:https://www.cnblogs.com/XBWer/p/2676174.html