POJ 1087 A Plug for UNIX (maximum network Stream)
POJ 1087 A Plug for UNIXLink: http://poj.org/problem? Id = 1087
Question:There are n (1 ≤ n ≤ 100) sockets, each of which is described using a alphanumeric string (up to 24 characters ). There are m (1 ≤ m ≤ 100) devices, each device has a name, and the name of the plug it uses; the name of the plug is the same as the name of the socket it uses; the device name is a string that contains up to 24 alphanumeric characters. The names of any two devices are different. There are k (1 ≤ k ≤ 100) converters, each converter can convert a socket into a plug.
Example:
4 A B C D 5 laptop B phone C pager B clock B comb X 3 B X X A X D
Ideas:Establish a settlement point, with each outlet connected to the edge. The traffic represents the number of such outlets. Create a source point. The source point is connected to each device. The traffic is 1. Each converter connects two sockets and the traffic is INF. Then find the maximum stream. The answer is the number of devices minus the maximum stream.
Details:This question is disgusting during graph creation. It should be noted that, among m devices and sockets and data of k converters, there may be devices that have never been seen before. Therefore, the socket information must be stored, and map can be used to store the corresponding points of the socket.
Code:
/* ID: wuqi9395@126.comPROG: LANG: C ++ */# include# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Define deusing namespace std; # define INF (1 <30) # define PI acos (-1.0) # define mem (a, B) memset (a, B, sizeof (a) # define rep (I, a, n) for (int I = a; I <n; I ++) # define per (I, a, n) for (int I = n-1; I> = a; I --) # define eps 1e-6 # define debug puts ("================ ") # define pb push_back // # define mp make_pair # define all (x ). begin (), (x ). end () # define fi first # define se second # define SZ (x) (int) (x ). size () # define POSIN (x, y) (0 <= (x) & (x) <n & 0 <= (y) & (y) <m) typedef long ll; typedef unsigned long ULL; const int maxn = 610; const int maxm = 2000000; int m, k; struct node {int v; // vertex int cap; // capacity int flow; // current flow in this arc int nxt;} e [maxm * 2]; int g [maxn], cnt; int st, ed, n; void add (int u, int v, int c) {e [++ cnt]. v = v; e [cnt]. cap = c; e [cnt]. flow = 0; e [cnt]. nxt = g [u]; g [u] = cnt; e [++ cnt]. v = u; e [cnt]. cap = 0; e [cnt]. flow = 0; e [cnt]. nxt = g [v]; g [v] = cnt;} map
Mp; map
: Iterator it; void init () {mem (g, 0); cnt = 1; mp. clear (); scanf ("% d", & n); char str [25]; ed = 0; int tot = 1, has [111] = {0 }; for (int I = 1; I <= n; I ++) {scanf ("% s", str); string ss (str); int now; if (mp [ss] = 0) {mp [ss] = tot; now = tot ++;} else now = mp [ss]; has [now] ++;} for (int I = 1; I <tot; I ++) add (I, ed, has [I]); scanf ("% d", & m); char s [25]; vector
V; for (int I = 0; I <m; I ++) {scanf ("% s", str, s); v. pb (tot); if (mp [s]) add (tot ++, mp [s], 1); else {mp [s] = tot + 1; add (tot, tot + 1, 1); tot + = 2 ;}} scanf ("% d", & k); for (int I = 0; I <k; I ++) {scanf ("% s", str, s); if (mp [str] = 0) mp [str] = tot ++; if (mp [s] = 0) mp [s] = tot ++; add (mp [str], mp [s], INF);} st = tot; for (int I = 0; I <v. size (); I ++) add (st, v [I], 1); n = tot + 3;} I Nt dist [maxn], numbs [maxn], q [maxn]; void rev_bfs () {int font = 0, rear = 1; for (int I = 0; I <= n; I ++) {// n indicates the total number of dist [I] = maxn; numbs [I] = 0;} q [font] = ed; dist [ed] = 0; numbs [0] = 1; while (font! = Rear) {int u = q [font ++]; for (int I = g [u]; I = e [I]. nxt) {if (e [I ^ 1]. cap = 0 | dist [e [I]. v] <maxn) continue; dist [e [I]. v] = dist [u] + 1; ++ numbs [dist [e [I]. v]; q [rear ++] = e [I]. v ;}}int maxflow () {rev_bfs (); int u, totalflow = 0; int curg [maxn], revpath [maxn]; for (int I = 0; I <= n; ++ I) curg [I] = g [I]; u = st; while (dist [st] <n) {if (u = ed) {// find an augmenting path int augf Low = INF; for (int I = st; I! = Ed; I = e [curg [I]. v) augflow = min (augflow, e [curg [I]. cap); for (int I = st; I! = Ed; I = e [curg [I]. v) {e [curg [I]. cap-= augflow; e [curg [I] ^ 1]. cap + = augflow; e [curg [I]. flow + = augflow; e [curg [I] ^ 1]. flow-= augflow;} totalflow + = augflow; u = st;} int I; for (I = curg [u]; I = e [I]. nxt) if (e [I]. cap> 0 & dist [u] = dist [e [I]. v] + 1) break; if (I) {// find an admissible arc, then Advance curg [u] = I; revpath [e [I]. v] = I ^ 1; u = e [I]. v;} else {// no admissible arc, Then relabel this vertex if (0 = (-- numbs [dist [u]) break; // GAP cut, Important! Curg [u] = g [u]; int mindist = n; for (int j = g [u]; j = e [j]. nxt) if (e [j]. cap> 0) mindist = min (mindist, dist [e [j]. v]); dist [u] = mindist + 1; ++ numbs [dist [u]; if (u! = St) u = e [revpath [u]. v; // Backtrack} return totalflow;} int main () {init (); printf ("% d \ n", m-maxflow (); return 0 ;}