zoukankan      html  css  js  c++  java
  • 1550: Simple String 最大流解法

    http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1550

    很久以前做的一题,当时队友用最大流做,现在我也是

    这个转化为二分图多重匹配,就是一样的意思了。

    设出一个原点S,两个人1,和2,S-->1的流量是n表明只能流出n个字母,s-->2的流量是n,一样含义。

    然后再设一个汇点T,表明需要有多少流进来,跑一发就好。

    #include <bits/stdc++.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    const int maxn = 100000 * 2;
    struct Edge {
        int u, v, w, tonext;
        int id;
    }e[maxn * 2];
    int first[maxn], num;
    void addEdge(int u, int v, int w) {
        e[num].u = u, e[num].v = v, e[num].w = w, e[num].tonext = first[u], e[num].id = num;
        first[u] = num++;
    }
    int flow[maxn], pre[maxn];
    int bfs(int be, int en) { //O(n * E * E)
        queue<int> que;
        memset(flow, false, sizeof flow);
        pre[be] = -1, flow[be] = inf;
        que.push(be);
        while (!que.empty()) {
            int cur = que.front();
            que.pop();
            for (int i = first[cur]; ~i; i = e[i].tonext) {
                int v = e[i].v;
                if (flow[v] == 0 && e[i].w > 0) {
                    pre[v] = e[i].id;
                    flow[v] = min(flow[cur], e[i].w);
                    que.push(v);
                }
            }
            if (flow[en]) break; //找到了增广路
        }
        if (flow[en] == 0) return -1;
        else return flow[en];
    }
    
    int maxFlow(int be, int en) {
        int sumFlow = 0;
        while (true) {
            int res = bfs(be, en);
            if (res == -1) { //找不到增广路
                break;
            }
            int edgeID = pre[en];
            while (edgeID != -1) {
                e[edgeID].w -= res;
                e[edgeID ^ 1].w += res;
                edgeID = pre[e[edgeID].u];
            }
            sumFlow += res;
        }
        return sumFlow;
    }
    char s1[maxn], s2[maxn], s3[maxn];
    int cnt1[222], cnt2[222], cnt3[222];
    void work() {
        memset(cnt1, 0, sizeof cnt1);
        memset(cnt2, 0, sizeof cnt2);
        memset(cnt3, 0, sizeof cnt3);
        memset(first, -1, sizeof first);
        num = 0;
        int lenstr = strlen(s1 + 1);
        addEdge(0, 1, lenstr / 2);
        addEdge(1, 0, 0);
        addEdge(0, 2, lenstr / 2);
        addEdge(2, 0, 0);
        for (int i = 1; i <= lenstr; ++i) {
            cnt1[s1[i]]++;
            cnt2[s2[i]]++;
            cnt3[s3[i]]++;
        }
        for (int i = 'A'; i <= 'Z'; ++i) {
            addEdge(1, i - 'A' + 3, cnt1[i]);
            addEdge(i - 'A' + 3, 1, 0);
            addEdge(2, i - 'A' + 3, cnt2[i]);
            addEdge(i - 'A' + 3, 2, cnt2[i]);
        }
        for (int i = 'A'; i <= 'Z'; ++i) {
            addEdge(i - 'A' + 3, 29, cnt3[i]);
            addEdge(29, i - 'A' + 3, 0);
        }
        int res = maxFlow(0, 29);
        if (res == lenstr) {
            printf("YES
    ");
        } else printf("NO
    ");
    }
    
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        while (scanf("%s%s%s", s1 + 1, s2 + 1, s3 + 1) > 0) work();
        return 0;
    }
    View Code
  • 相关阅读:
    从HDFS下载文件到本地
    oracle jdbc jar包异常
    spring jdbctemplate 启动报错(oracle驱动bug)
    solr搜索异常
    jdbc 处理Clob
    Wavosaur音频编辑软件: 功能专业,体积超小(500KB)
    isa server 2004中找不到HTTP过滤选项。
    cisco pix logging facility含义
    IPSec基础-密钥交换和密钥保护
    cisco 831 使用 SDM
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/7045087.html
Copyright © 2011-2022 走看看