poj 1087 A Plug for UNIX

其实网络流的题目习惯之后建图还是挺容易的。

习惯,好深奥啊。。。

#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;
}

你可能感兴趣的:(poj 1087 A Plug for UNIX)