1.题面
http://poj.org/problem?id=3281
2.题意
已知牛的数量n,饮料的种类d,食物的种类,以及每头牛喜欢的食物和饮料,希望你求出最合理的搭配,使最终能吃到饭的牛的数量最多
3.思路
网络流最大流,思路很简单,不说了
4.代码
/***************************************************************** > File Name: cpp_acm.cpp > Author: Uncle_Sugar > Mail: [email protected] > Created Time: Mon 03 Oct 2016 19:01:17 CST *****************************************************************/ # include <cstdio> # include <cstring> # include <cctype> # include <cmath> # include <cstdlib> # include <climits> # include <iostream> # include <iomanip> # include <set> # include <map> # include <vector> # include <stack> # include <queue> # include <algorithm> using namespace std; # define rep(i,a,b) for (i=a;i<=b;i++) # define rrep(i,a,b) for (i=b;i>=a;i--) # define mset(aim, val) memset(aim, val, sizeof(aim)) struct QuickIO{ QuickIO(){const int SZ = 1<<20; setvbuf(stdin ,new char[SZ],_IOFBF,SZ); setvbuf(stdout,new char[SZ],_IOFBF,SZ); } //*From programcaicai*// }QIO; template<class T>void PrintArray(T* first,T* last,char delim=' '){ for (;first!=last;first++) cout << *first << (first+1==last?'\n':delim); } /* 1.see the size of the input data before you select your algorithm 2.cin&cout is not recommended in ACM/ICPC 3.pay attention to the size you defined, for instance the size of edge is double the size of vertex */ const int debug = 1; //# const int size = 10 + ; const int INF = INT_MAX>>1; typedef long long ll; const int MAXN = 510; const int MAXM = MAXN*MAXN; struct Edge{ int to, f, nxt; }edge[MAXM]; int tot = 0; int head[MAXN]; void init(){ tot = 0; memset(head, -1, sizeof(head)); } void addedge(int from, int to, int f){ edge[tot].to = to;edge[tot].f = f; edge[tot].nxt = head[from]; head[from] = tot++; edge[tot].to = from;edge[tot].f = 0; edge[tot].nxt = head[to]; head[to] = tot++; } int level[MAXN]; bool bfs(int s, int t){ static queue<int> que; while (!que.empty()) que.pop(); memset(level, 0, sizeof(level)); que.push(s); level[s] = 1; while (!que.empty()){ int cur = que.front(); que.pop(); if (cur == t) return true; for (int e = head[cur]; ~e; e = edge[e].nxt){ int to = edge[e].to, f = edge[e].f; if (!level[to] && f){ level[to] = level[cur] + 1; que.push(to); } } } return false; } int dfs(int u, int t, int sup){ if (u == t) return sup; int ret = 0; for (int e = head[u]; ~e; e = edge[e].nxt){ int cur = edge[e].to, f = edge[e].f; if (level[cur] == level[u] + 1 && f){ int mi = min(sup - ret, f); int tf = dfs(cur, t, mi); edge[e].f -= tf; edge[e^1].f += tf; ret += tf; } if (ret == sup) return ret; } return ret; } int Dinic(int s, int t){ int ret = 0; while (bfs(s, t)) ret += dfs(s, t, INF); return ret; } int main() { /*std::ios::sync_with_stdio(false);cin.tie(0);*/ int n, f, d; while (~scanf("%d%d%d", &n, &f, &d)){ init(); int s = 0, t = f + n + n + d + 1; for (int i = 1; i <= f; i++) addedge(s, i, 1); for (int i = 1; i <= n; i++) addedge(f + i, f + n + i, 1); for (int i = 1; i <= d; i++) addedge(f + n + n + i, t, 1); for (int i = 1; i <= n; i++){ int a, b, tmp; scanf("%d%d", &a, &b); while (a--){ scanf("%d", &tmp); addedge(tmp, f + i, 1); } while (b--){ scanf("%d", &tmp); addedge(f + n + i, f + n + n + tmp, 1); } } int ans = Dinic(s, t); printf("%d\n", ans); } return 0; }