zoukankan      html  css  js  c++  java
  • 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("");
        }
    }
    
  • 相关阅读:
    SVN服务器搭建(一)
    排序算法二:冒泡排序
    【LeetCode】136. Single Number
    【LeetCode】217. Contains Duplicate
    【LeetCode】189. Rotate Array
    【LeetCode】122. Best Time to Buy and Sell Stock II
    【LeetCode】26. Remove Duplicates from Sorted Array
    【LeetCode】20. Valid Parentheses
    【LeetCode】680. Valid Palindrome II
    【LeetCode】345. Reverse Vowels of a String
  • 原文地址:https://www.cnblogs.com/ruthank/p/10910587.html
Copyright © 2011-2022 走看看