POJ--3281(最大流,拆点)

2014-12-20 18:05:00

思路:嘛,这题终于不是max-flow果题了。

  因为种种限制,需要将牛进行拆点,从而限制每头牛只能选择一种dish和一种drink,每头牛拆为两点,点间建边,容量为1。

  (我本来是将dish拆点的,怎么想都觉得对,后来发现如果按照牛 -> dish_in -> dish_out -> drink这样建图的话,为使得dish_out和drink之间的边不具有牛的编号性,即各条边不知道是哪个牛的选择,可能有些牛不喜欢某种搭配,但因为其他牛喜欢这种搭配而强行被当成一条通路了,自然就WA了)

  

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <vector>
 6 #include <map>
 7 #include <set>
 8 #include <stack>
 9 #include <queue>
10 #include <iostream>
11 #include <algorithm>
12 using namespace std;
13 #define lp (p << 1)
14 #define rp (p << 1|1)
15 #define getmid(l,r) (l + (r - l) / 2)
16 #define MP(a,b) make_pair(a,b)
17 typedef long long ll;
18 typedef unsigned long long ull;
19 const int INF = 1 << 30;
20 const int maxn = 1000;
21 
22 int N,F,D;
23 int cp[maxn][maxn],ed,lev[maxn];
24 int Q[maxn],head,rear;
25 
26 void Bfs(){
27     memset(lev,-1,sizeof(lev));
28     Q[head = rear = 1] = 0;
29     lev[0] = 0;
30     while(head <= rear){
31         int x = Q[head++];
32         for(int i = 1; i <= ed; ++i) if(lev[i] < 0 && cp[x][i] > 0){
33             lev[i] = lev[x] + 1;
34             Q[++rear] = i;
35         }
36     }
37 }
38 
39 int Dfs(int p,int minf){
40     if(p == ed) return minf;
41     for(int i = 1; i <= ed; ++i) if(lev[i] > lev[p] && cp[p][i] > 0){
42         int d = Dfs(i,min(cp[p][i],minf));
43         if(d > 0){
44             cp[p][i] -= d;
45             cp[i][p] += d;
46             return d;
47         }
48     }
49     return 0;
50 }
51 
52 int Dinic(){
53     int max_flow = 0,plus;
54     while(1){
55         Bfs();
56         if(lev[ed] < 0) break;
57         while((plus = Dfs(0,INF)) > 0) max_flow += plus;
58     }
59     return max_flow;
60 }
61 
62 int main(){
63     memset(cp,0,sizeof(cp));
64     int a,b,c,tmp[maxn];
65     scanf("%d%d%d",&N,&F,&D);
66     ed = F + N + N + D + 1;
67     for(int i = 1; i <= F; ++i) cp[0][i] = 1; //source to food
68     for(int i = 1; i <= N; ++i) cp[F + i][F + N + i] = 1; //cows-in to cows-out
69     for(int i = 1; i <= D; ++i) cp[F + N + N + i][ed] = 1; //drinks to ed
70     for(int i = 1; i <= N; ++i){ //food to cows-in and cows-out to drinks
71         scanf("%d%d",&a,&b);
72         for(int j = 1; j <= a; ++j){
73             scanf("%d",&c);
74             cp[c][F + i] = 1;
75         }
76         for(int j = 1; j <= b; ++j){
77             scanf("%d",&c);
78             cp[F + N + i][F + N + N + c] = 1;
79         }
80     }
81     printf("%d\n",Dinic());
82     return 0;
83 }

 

posted @ 2014-12-20 18:09  Naturain  阅读(100)  评论(0编辑  收藏  举报