最大流(多个源点,多个汇点) 之 poj 1274
// [5/28/2014 Sjm]
/*
最大流:多个源点,多个汇点
// 若按二分图匹配做,请参见:http://www.cnblogs.com/shijianming/p/4140846.html 思路: 1)增加一个超级源点 S,从 S 向 每个源点 连一条容量为对应最大流出流量的边 2)增加一个超级汇点 T,从 每一个汇点 向 T 连一条容量为对应最大流入容量的边 对于此题: 源点 cows (范围:M+1 ~ M+N),汇点 stalls (范围:1 ~ M) 设 cows 与 the stalls (in which that cow is willing to produce milk)之间的容量为 1 1)设 0 为超级源点, 因为每个 cow 流出的最大流出流量为 1(只能连一个stall),所以得:超级源点 向每个 cows 的连线的流量为 1 2)设 M+N+1 为超级汇点 因为流入每个 stall 最大流量为 1(只能被一个cow连接),所以得:每个 stall 向 超级汇点 的连线的连线的流量为 1 */
1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <vector> 5 #include <algorithm> 6 using namespace std; 7 const int MAX_V = 410; 8 const int INF = 0x3f3f3f3f; 9 int N, M; 10 11 struct edge { int to, cap, rev; }; 12 vector<edge> G[MAX_V]; 13 bool used[MAX_V]; 14 15 void add_edge(int from, int to, int cap) 16 { 17 edge e1 = { to, cap, G[to].size() }; 18 G[from].push_back(e1); 19 edge e2 = { from, 0, G[from].size() - 1 }; 20 G[to].push_back(e2); 21 } 22 23 int dfs(int v, int t, int f) 24 { 25 if (v == t) return f; 26 used[v] = true; 27 for (int i = 0; i < G[v].size(); i++) { 28 edge &e = G[v][i]; 29 if (!used[e.to] && (e.cap > 0)) { 30 int d = dfs(e.to, t, min(f, e.cap)); 31 if (d > 0) { 32 e.cap -= d; 33 G[e.to][e.rev].cap += d; 34 return d; 35 } 36 } 37 } 38 return 0; 39 } 40 41 int Solve(int s, int t) 42 { 43 int flow = 0; 44 for (;;) 45 { 46 memset(used, 0, sizeof(used)); 47 int f = dfs(s, t, INF); 48 if (!f) return flow; 49 flow += f; 50 } 51 } 52 53 int main() 54 { 55 //freopen("input.txt", "r", stdin); 56 //freopen("output.txt", "w", stdout); 57 while (~scanf("%d %d", &N, &M)) 58 { 59 for (int i = 1; i <= N; i++) { 60 int mycount; 61 scanf("%d", &mycount); 62 int tep; 63 for (int j = 0; j < mycount; j++) { 64 scanf("%d", &tep); 65 add_edge(M + i, tep, 1); 66 } 67 } 68 for (int i = 1; i <= N; i++) { 69 add_edge(0, M+i, 1); 70 } 71 for (int i = 1; i <= M; i++) { 72 add_edge(i, M + N + 1, 1); 73 } 74 printf("%d\n", Solve(0, M + N + 1)); 75 for (int i = 0; i < MAX_V; i++) { 76 G[i].clear(); 77 } 78 } 79 return 0; 80 }