POJ1087-A Plug for UNIX(最大流)
阿新 • • 發佈:2020-07-16
題意:買了n個插座,m個電器,k個轉換器。\(n(1 <= n <= 100)(1 <= m <= 100)(1 <= k <= 100)\),轉換器會把\(s1 s2\)中的s2插座轉換成s1插座。
//插座個數
4
A
B
C
D
//插頭個數
5
laptop B
phone C
pager B
clock B
comb X
//轉換器種類
3
B X
X A
X D
分析:我們可以用map為每個插座賦值一個id,我們從源點向插座連一條容量為1的邊,因為每個插座只能適配一個插頭。其次,我們為每個插頭也賦值一個id,從適配的插座向插頭連邊,容量為1。然後插頭再向匯點連邊。我們的交換器比如\(s1 s2\)
注意:每次賦值都要判斷一個型別的插座或者插頭是否存在。
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <map> #include <queue> #include <algorithm> using namespace std; const int inf = 1 << 29, N = 2005, M = 2 * N; int h[N], e[M], ne[M], d[N]; int w[M]; int s, t, idx, maxflow; void add(int a, int b, int c) { e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++; e[idx] = a, w[idx] = 0, ne[idx] = h[b], h[b] = idx++; } //構造分層圖 bool bfs() { memset(d, 0, sizeof d); queue<int> q; q.push(s), d[s] = 1; while (q.size()) { int u = q.front(); q.pop(); for (int i = h[u]; i != -1; i = ne[i]) { int j = e[i]; if (w[i] && !d[j]) { q.push(j); d[j] = d[u] + 1; if (j == t) return true; } } } return false; } int dinic(int u, int flow) { if (u == t) return flow; int rest = flow, k; for (int i = h[u]; i != -1 && rest; i = ne[i]) { int j = e[i]; if (w[i] && d[j] == d[u] + 1) { k = dinic(j, min(rest, w[i])); if (!k) d[j] = 0; w[i] -= k; w[i ^ 1] += k; rest -= k; } } return flow - rest; } map<string, int> mp; int main() { memset(h, -1, sizeof h); s = 0, t = 1000; //插座個數 int n; scanf("%d", &n); string name, name2; int id = 0; for (int i = 1; i <= n; ++i) { cin >> name; mp[name] = ++id; //源點向插座連邊 add(s, id, 1); } int m; //插頭個數 scanf("%d", &m); for (int i = 1; i <= m; ++i) { //插頭名和插頭型別 cin >> name >> name2; mp[name] = ++id; if (mp.find(name2) == mp.end()) { mp[name2] = ++id; } //插座向插頭連邊 add(mp[name2], mp[name], 1); //插頭向匯點連邊 add(mp[name], t, 1); } int k; scanf("%d", &k); for (int i = 1; i <= k; ++i) { cin >> name >> name2; if (mp.find(name) == mp.end()) mp[name] = ++id; if (mp.find(name2) == mp.end()) mp[name2] = ++id; add(mp[name2], mp[name], inf); } int flow = 0; while (bfs()) { while (flow = dinic(s, inf)) maxflow += flow; } printf("%d\n", m - maxflow); return 0; }