• UVA


    题意

    给定一些插头设备和插座,有一些方法可以把其中一些插头变成另一种插头。求无法匹配插座的插头设备个数。

    题解

    (map)给每个字符串标号为(a_i)(b_i)

    读入每种改变插头的方法,连边,权值为(inf)

    然后连边(S longrightarrow a_i),权值为(1)(b_i longrightarrow T),权值为(1)

    跑最大流即可。

    代码

    #include <bits/stdc++.h>
    
    #define FOPI freopen("in.txt", "r", stdin)
    #define FOPO freopen("out.txt", "w", stdout)
    #define FOR(i,x,y) for (int i = x; i <= y; i++)
    #define ROF(i,x,y) for (int i = x; i >= y; i--)
    
    using namespace std;
    typedef long long LL;
    const int inf = 0x3f3f3f3f;
    const int maxn = 1e5 + 100;
    const int maxm = 2e5 + 100;
    
    
    struct Edge
    {
        int to, next, cap, flow;
    }edge[maxm];
    
    int tot;
    int head[maxn];
    
    void init()
    {
        tot = 2;
        memset(head, -1, sizeof(head));
    }
    
    void build(int u, int v, int w, int rw = 0)
    {
        edge[tot].to = v; edge[tot].cap = w; edge[tot].flow = 0;
        edge[tot].next = head[u]; head[u] = tot++;
    
        edge[tot].to = u; edge[tot].cap = 0; edge[tot].flow = 0;
        edge[tot].next = head[v]; head[v] = tot++;
    }
    
    int Q[maxn];
    int dep[maxn], cur[maxn], sta[maxn];
    
    bool bfs(int s, int t, int n)
    {
        int front = 0, tail = 0;
        memset(dep, -1, sizeof(dep[0]) * (n+1));
        dep[s] = 0;
        Q[tail++] = s;
        while(front < tail)
        {
            int u = Q[front++];
            for (int i = head[u]; i != -1; i = edge[i].next)
            {
                int v = edge[i].to;
                if (edge[i].cap > edge[i].flow && dep[v] == -1)
                {
                    dep[v] = dep[u] + 1;
                    if (v == t) return true;
                    Q[tail++] = v;
                }
            }
        }
        return false;
    }
    
    LL dinic(int s, int t, int n)
    {
        LL maxflow = 0;
        while(bfs(s, t, n))
        {
            for (int i = 0; i < n; i++) cur[i] = head[i];
            int u = s, tail = 0;
            while(cur[s] != -1)
            {
                if (u == t)
                {
                    int tp = inf;
                    for (int i = tail-1; i >= 0; i--)
                        tp = min(tp, edge[sta[i]].cap - edge[sta[i]].flow);
    
                    //if (tp >= inf) return -1;
                    maxflow += tp;
    
                    for (int i = tail-1; i >= 0; i--)
                    {
                        edge[sta[i]].flow += tp;
                        edge[sta[i]^1].flow -= tp;
                        if (edge[sta[i]].cap - edge[sta[i]].flow == 0) tail = i;
                    }
                    u = edge[sta[tail]^1].to;
                }
                else if (cur[u] != -1 && edge[cur[u]].cap > edge[cur[u]].flow
                         && dep[u]+1 == dep[edge[cur[u]].to])
                {
                    sta[tail++] = cur[u];
                    u = edge[cur[u]].to;
                }
                else
                {
                    while(u != s && cur[u] == -1) u = edge[sta[--tail]^1].to;
                    cur[u] = edge[cur[u]].next;
                }
            }
        }
        return maxflow;
    }
    
    int t;
    int a[205], b[205];
    string s, r;
    map<string, int> M;
    int n, m, S, T, cnt, q;
    
    int getid(string &s)
    {
        if (M.count(s)) return M[s];
        return M[s] = ++cnt;
    }
    
    int main()
    {
    //    FOPI;
    //    FOPO;
    
        ios::sync_with_stdio(false);
        cin.tie(NULL);
    
        cin >> t;
        FOR(ca, 1, t)
        {
            init();
            M.clear(); cnt = 0;
    
            cin >> n;
            FOR(i, 1, n) { cin >> s; a[i] = getid(s); }
    
            cin >> m;
            FOR(i, 1, m) { cin >> r >> s; b[i] = getid(s); }
    
            cin >> q;
            FOR(i, 1, q)
            {
                cin >> s >> r;
                int x = getid(s), y = getid(r);
                build(y, x, inf);
            }
    
            S = 0, T = cnt+1;
            FOR(i, 1, n) build(S, a[i], 1);
            FOR(j, 1, m) build(b[j], T, 1);
    
            LL ans = dinic(S, T, T);
            printf("%lld
    ", m-ans);
    
            if (ca != t) puts("");
        }
    }
    
  • 相关阅读:
    读书笔记之:Accelerated C++ 中文版[+]
    读书笔记之:C程序设计语言(第2版)[+++++]
    读书笔记之:C++精解与程序设计[]
    C/C++中的输入与输出及如何读取一行文本
    C/C++中的getline函数总结
    JM中的一些问题总结
    YUV主要采样格式理解
    读书笔记之:C++ Primer (第4版)及习题(ch12ch18) [++++]
    读书笔记之:C++ Primer (第4版)及习题(ch01ch11) [++++]
    读书笔记之:C++精髓·软件工程[]
  • 原文地址:https://www.cnblogs.com/ruthank/p/10910587.html
Copyright © 2020-2023  润新知