POJ-1087 A Plug for UNIX
题意
有$n$个插座,m个用电器,每个用电器都对应一个插头(插头类型与插座相同则可插入充电),$k$种转换器(每种数量无限),$s_1$ $s_2$表示一个$s_2$类型插座可以转换成一个$s_1$类型插座,问最少有几个用电器无法同时充电。
思路
可建图用最大流求解,源点指向$n$个插座,$m$个用电器指向汇点,插座指向对应的用电器,容量均为1,对于一个转换器$(s_1,s_2)$,插座$s_2$指向$s_1$,容量为无穷大。最大流表示可同时充电的最大充电器数量,用$m$减去最大流即为答案。
代码实现
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <queue> #include <map> using std::queue; using std::map; using std::cin; using std::cout; using std::endl; using std::string; const int INF = 0x3f3f3f3f, N = 500, M = 1000; int head[N], d[N]; int s, t, tot, maxflow; struct Edge { int to, cap, nex; } edge[M]; queue<int> q; void add(int x, int y, int z) { edge[++tot].to = y, edge[tot].cap = z, edge[tot].nex = head[x], head[x] = tot; edge[++tot].to = x, edge[tot].cap = 0, edge[tot].nex = head[y], head[y] = tot; } bool bfs() { memset(d, 0, sizeof(d)); while (q.size()) q.pop(); q.push(s); d[s] = 1; while (q.size()) { int x = q.front(); q.pop(); for (int i = head[x]; i; i = edge[i].nex) { int v = edge[i].to; if (edge[i].cap && !d[v]) { q.push(v); d[v] = d[x] + 1; if (v == t) return true; } } } return false; } int dinic(int x, int flow) { if (x == t) return flow; int rest = flow, k; for (int i = head[x]; i && rest; i = edge[i].nex) { int v = edge[i].to; if (edge[i].cap && d[v] == d[x] + 1) { k = dinic(v, std::min(rest, edge[i].cap)); if (!k) d[v] = 0; edge[i].cap -= k; edge[i^1].cap += k; rest -= k; } } return flow - rest; } void init() { tot = 1, maxflow = 0; s = 0, t = 1; memset(head, 0, sizeof(head)); } int main() { int n, m, k; while (cin >> n) { init(); int idx = 1; string s1, s2; map<string, int> mp; for (int i = 0; i < n; i++) { cin >> s1; if (!mp[s1]) mp[s1] = ++idx; add(0, mp[s1], 1); } cin >> m; for (int i = 0; i < m; i++) { cin >> s1 >> s2; if (!mp[s1]) mp[s1] = ++idx; if (!mp[s2]) mp[s2] = ++idx; add(mp[s2], mp[s1], 1); add(mp[s1], 1, 1); } cin >> k; for (int i = 0; i < k; i++) { cin >> s1 >> s2; if (!mp[s1]) mp[s1] = ++idx; if (!mp[s2]) mp[s2] = ++idx; add(mp[s2], mp[s1], INF); } while (bfs()) maxflow += dinic(s, INF); cout << (m - maxflow) << endl; } return 0; }
作者:_kangkang
本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。