其实网络流的题目习惯之后建图还是挺容易的。
习惯,好深奥啊。。。
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <cmath> #include <vector> #include <map> using namespace std; const int INF = 1 << 20; const int MaxN = 1005; struct NetWork { struct Adj { int v, c, b; Adj() {} Adj(int _v, int _c, int _b) : v(_v), c(_c), b(_b) {} }; int n, s, t, h[MaxN], cnt[MaxN]; vector<Adj> adj[MaxN]; void clear() { for(int i = 0; i < n; i++) { adj[i].clear(); } n = 0; } void add_edge(int u, int v, int c) { n = max( n, max(u, v) + 1 ); adj[u].push_back(Adj(v, c, adj[v].size())); adj[v].push_back(Adj(u, 0, adj[u].size() - 1)); } int max_flow(int _s, int _t) { s = _s, t = _t; fill(h, h + n, 0); fill(cnt, cnt + n, 0); int flow = 0; while(h[s] < n) { flow += dfs(s, INF); } return flow; } int dfs(int u, int flow) { if(u == t) return flow; int minh = n - 1, ct = 0; for(vector<Adj>::iterator it = adj[u].begin(); flow && it != adj[u].end(); it++) { if(it->c) { if(h[it->v] + 1 == h[u]) { int k = dfs(it->v, min(it->c, flow)); if(k) { it->c -= k; adj[it->v][it->b].c += k; flow -= k; ct += k; } if(h[s] >= n) return ct; } minh = min(minh, h[it->v]); } } if(ct) return ct; if(--cnt[ h[u] ] == 0) h[s] = n; h[u] = minh + 1; ++cnt[h[u]]; return 0; } }network; int n, m, k; map<string, int> id1, id2; int total1, total2; map<int, int> mp; int main() { while(1 == scanf("%d", &n)) { id1.clear(); total1 = 0; for(int i = 1; i <= n; i++) { string s; cin >> s; if(id1[s] == 0) id1[s] = ++total1; } int id = total1; scanf("%d", &m); id2.clear(); total2 = 0; mp.clear(); for(int i = 0; i < m; i++) { string s1, s2; cin >> s1 >> s2; if(id2[s1] == 0) id2[s1] = ++total2; if(id1[s2] == 0) id1[s2] = ++total1; mp[id2[s1]] = id1[s2]; } int s = 0; network.clear(); for(int i = 1; i <= total2; i++) { network.add_edge(s, i, 1); } for(map<int, int>::iterator it = mp.begin(); it != mp.end(); it++) { network.add_edge(it->first, it->second + total2, 1); } scanf("%d", &k); for(int i = 0; i < k; i++) { string s1, s2; cin >> s1 >> s2; if(id1[s1] == 0) id1[s1] = ++total1; if(id1[s2] == 0) id1[s2] = ++total1; network.add_edge(id1[s1] + total2, id1[s2] + total2, INF); } int t = total1 + total2 + 1; for(int i = 1; i <= id; i++) { network.add_edge(total2 + i, t, 1); } int res = network.max_flow(s, t); printf("%d\n", m - res); } return 0; }