poj3281 Dining

传送门

给定n头牛 a种食物 b种饮料

每种食物/饮料只能用一次

一头牛有限定的食物/饮料选择集合

食物饮料均满足则统计个数++ 求最大个数

Solution:

每个牛只配一次 所以拆点

然后就食物连源点 饮料连汇点

牛左右部连边

每个牛左边连食物右边连饮料

上述所有边权均为1

直接最大流完事

(发blog的顺序好像和做的顺序不大一样)

(感觉main压成一行好爽)

Code:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<queue>
 4 #include<iostream>
 5 #include<algorithm>
 6 #define ms(a,b) memset(a,b,sizeof a)
 7 #define rep(i,a,n) for(int i = a;i <= n;i++)
 8 #define per(i,n,a) for(int i = n;i >= a;i--)
 9 #define inf 2147483647
10 using namespace std;
11 typedef long long ll;
12 typedef double D;
13 #define eps 1e-8
14 ll read() {
15     ll as = 0,fu = 1;
16     char c = getchar();
17     while(c < '0' || c > '9') {
18         if(c == '-') fu = -1;
19         c = getchar();
20     }
21     while(c >= '0' && c <= '9') {
22         as = as * 10 + c - '0';
23         c = getchar();
24     }
25     return as * fu;
26 }
27 const int N = 10005;
28 //head
29 int n,A,B;
30 int s = N-1,t = N-2;
31 int head[N],nxt[N<<1],mo[N<<1],cst[N<<1],cnt = 1;
32 void _add(int x,int y,int w) {
33     mo[++cnt] = y;
34     cst[cnt] = w;
35     nxt[cnt] = head[x];
36     head[x] = cnt;
37 }
38 void add(int x,int y) {if(x^y) _add(x,y,1),_add(y,x,0);}
39 
40 int dep[N],cur[N];
41 bool bfs() {
42     queue<int> q;
43     memcpy(cur,head,sizeof cur);
44     ms(dep,0),q.push(s),dep[s] = 1;
45     while(!q.empty()) {
46         int x = q.front();
47         q.pop();
48         for(int i = head[x];i;i = nxt[i]) {
49             int sn = mo[i];
50             if(!dep[sn] && cst[i]) {
51                 dep[sn] = dep[x] + 1;
52                 q.push(sn);
53             }
54         }
55     }
56     return dep[t];
57 }
58 
59 int dfs(int x,int flow) {
60     if(x == t || flow == 0) return flow;
61     int res = 0;
62     for(int &i = cur[x];i;i = nxt[i]) {
63         int sn = mo[i];
64         if(dep[sn] == dep[x] + 1 && cst[i]) {
65             int d = dfs(sn,min(cst[i],flow - res));
66             if(d) {
67                 cst[i] -= d,cst[i^1] += d;
68                 res += d;
69                 if(res == flow) break;
70             }
71         }
72     }
73     if(res ^ flow) dep[x] = 0;
74     return res;
75 }
76 
77 int DINIC() {
78     int ans = 0;
79     while(bfs()) ans += dfs(s,inf);
80     return ans;
81 }
82 
83 int idx(int x,int f) {return x + f * 1005;}
84 
85 void init() {
86     n = read(),A = read(),B = read();
87     rep(i,1,n) {
88         int X = read(),Y = read();
89         rep(j,1,X) add(idx(read(),0),idx(i,1));
90         rep(j,1,Y) add(idx(i,2),idx(read(),3));
91         add(idx(i,1),idx(i,2));
92     }
93     rep(i,1,A) add(s,idx(i,0));
94     rep(i,1,B) add(idx(i,3),t);
95 }
96 
97 int main() {init(),printf("%d\n",DINIC());}

猜你喜欢

转载自www.cnblogs.com/yuyanjiaB/p/10011966.html