• [CF Edu 80] Red-Blue Graph


    题目: [CF Edu 80] Red-Blue Graph

    链接:https://codeforces.com/contest/1288/problem/F

    分析:

    原来在费用流里必选一条边还能用-inf来控制,原谅我孤陋寡闻了

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int MAXN = 410;
    const int MAXM = MAXN * 10;
    const int inf = 1e6;
    const LL INF = 1e18;
    namespace NWF{
        struct Edge {
            int to, nxt;LL f, c;
        } e[MAXM << 1]; 
        int S, T, tot;
        int ecnt, head[MAXN], cur[MAXN];LL dis[MAXN];
        bool exist[MAXN];
        queue<int> q;
        void init(int _S, int _T, int _tot){
            ecnt = 1; S = _S; T = _T; tot = _tot;
            memset(head, 0, (tot + 1) * sizeof(int));
        } 
        void addEdge(int u, int v, LL f, LL c) {
            e[++ecnt] = (Edge) {v, head[u], f, c}; head[u] = ecnt;
            e[++ecnt] = (Edge) {u, head[v], 0,-c}; head[v] = ecnt;
        }
        bool spfa() {
            for(int i = 0;i <= tot; ++i){
                dis[i] = INF; cur[i] = exist[i] = 0;
            }
            q.push(S);dis[S] = 0;exist[S] = 1;
            while(!q.empty()) {
                int u = q.front(), v; q.pop();exist[u] = 0;
                for(int i = head[u]; i; i = e[i].nxt) {
                    if(e[i].f && dis[v = e[i].to] > dis[u] + e[i].c) {
                        dis[v] = dis[u] + e[i].c;
                        cur[v] = i;
                        if(!exist[v]) {
                            q.push(v);
                            exist[v] = 1;
                        }
                    }
                }
            }
            return dis[T] != INF;
        }
        LL mcmf() {
            LL cost = 0;
            while(spfa() && dis[T] < 0) {
                LL flow = INF;
                for(int i = T; i != S; i = e[cur[i] ^ 1].to)
                    flow = min(flow, e[cur[i]].f);
                for(int i = T; i != S; i = e[cur[i] ^ 1].to) {
                    e[cur[i]].f -= flow;
                    e[cur[i] ^ 1].f += flow;
                }
                cost += flow * dis[T];
            }
            return cost;
        }
    }
    int msk[MAXN];
    int main() {
        int n1, n2, m, r, b, cnt = 0;
        cin >> n1 >> n2 >> m >> r >> b;
        string col1, col2;
        cin >> col1;
        NWF::init(0, n1 + n2 + 1, n1 + n2 + 2);
        for(int i = 1; i <= n1; i++) {
            if(col1[i-1]=='R') NWF::addEdge(NWF::S, i, 1, -inf) , cnt++;
            if(col1[i-1]=='B') NWF::addEdge(i, NWF::T, 1, -inf) , cnt++;
            if(col1[i-1]!='B') NWF::addEdge(NWF::S, i, inf, 0);
            if(col1[i-1]!='R') NWF::addEdge(i, NWF::T, inf, 0);
        }
        cin >> col2; 
        for(int i = 1; i <= n2; i++) {
            if(col2[i-1]=='R') NWF::addEdge(i+n1, NWF::T, 1, -inf), cnt++;
            if(col2[i-1]=='B') NWF::addEdge(NWF::S, i+n1, 1, -inf), cnt++;
            if(col2[i-1]!='B') NWF::addEdge(i+n1,NWF::T, inf, 0);
            if(col2[i-1]!='R') NWF::addEdge(NWF::S,i+n1, inf, 0);
        }
        for(int i = 1, u, v; i <= m; i++) {
            cin >> u >> v; v += n1;
            NWF::addEdge(u, v, 1, r);
            NWF::addEdge(v, u, 1, b);
            msk[i] = NWF::ecnt - 3;
        }
        LL ans = NWF::mcmf()+(LL)cnt*inf;
        if(ans >= inf) cout << "-1" <<endl;
        else{
            cout << ans << endl;
            for(int i = 1; i <= m; i++)
                cout << (NWF::e[msk[i]].f == 0 ?'R': NWF::e[msk[i]+2].f==0?'B':'U');
            printf("
    ");
        }
        return 0;
    }

    上下界网络流

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int MAXN = 410;
    const int MAXM = MAXN * 10;
    const int inf = 1e6;
    const LL INF = 1e18;
    namespace NWF{
        struct Edge {
            int to, nxt;LL f, c;
        } e[MAXM << 1]; 
        int S, T, tot;
        int ecnt, head[MAXN], cur[MAXN];LL dis[MAXN];
        bool exist[MAXN];
        queue<int> q;
        void init(int _S, int _T, int _tot){
            ecnt = 1; S = _S; T = _T; tot = _tot;
            memset(head, 0, (tot + 1) * sizeof(int));
        } 
        void addEdge(int u, int v, LL f, LL c) {
            e[++ecnt] = (Edge) {v, head[u], f, c}; head[u] = ecnt;
            e[++ecnt] = (Edge) {u, head[v], 0,-c}; head[v] = ecnt;
        }
        bool spfa() {
            for(int i = 0;i <= tot; ++i){
                dis[i] = INF; cur[i] = exist[i] = 0;
            }
            q.push(S);dis[S] = 0;exist[S] = 1;
            while(!q.empty()) {
                int u = q.front(), v; q.pop();exist[u] = 0;
                for(int i = head[u]; i; i = e[i].nxt) {
                    if(e[i].f && dis[v = e[i].to] > dis[u] + e[i].c) {
                        dis[v] = dis[u] + e[i].c;
                        cur[v] = i;
                        if(!exist[v]) {
                            q.push(v);
                            exist[v] = 1;
                        }
                    }
                }
            }
            return dis[T] != INF;
        }
        LL mcmf() {
            LL cost = 0;
            while(spfa()) {
                LL flow = INF;
                for(int i = T; i != S; i = e[cur[i] ^ 1].to)
                    flow = min(flow, e[cur[i]].f);
                for(int i = T; i != S; i = e[cur[i] ^ 1].to) {
                    e[cur[i]].f -= flow;
                    e[cur[i] ^ 1].f += flow;
                }
                cost += flow * dis[T];
            }
            return cost;
        }
        bool check() {
            for(int i = head[S]; i; i = e[i].nxt) {
                if(e[i].f)return true;
            }
            return false;
        }
    }
    int msk[MAXN];
    int main() {
        int n1, n2, m, r, b;
        cin >> n1 >> n2 >> m >> r >> b;
        string col1, col2;
        cin >> col1;
        int CS = 0, CT = n1+n2+1, outCS = 0, inCT = 0;
        NWF::init(CT+1, CT+2, CT + 3);
        for(int i = 1; i <= n1; i++) {
            if(col1[i-1]=='R') {
                NWF::addEdge(NWF::S, i, 1, 0);
                NWF::addEdge(CS, i, inf, 0);
                ++outCS;
            }
            if(col1[i-1]=='B') {
                NWF::addEdge(i, NWF::T, 1, 0);
                NWF::addEdge(i, CT, inf, 0);
                ++inCT;
            }
            if(col1[i-1]=='U') {
                NWF::addEdge(CS, i, inf, 0);
                NWF::addEdge(i, CT, inf, 0);
            }
        }
        cin >> col2; 
        for(int i = 1; i <= n2; i++) {
            if(col2[i-1]=='R') {
                NWF::addEdge(i+n1, NWF::T, 1, 0);
                NWF::addEdge(i+n1, CT, inf, 0);
                ++inCT;
            }
            if(col2[i-1]=='B') {
                NWF::addEdge(NWF::S, i+n1, 1, 0);
                NWF::addEdge(CS, i+n1, inf, 0);
                ++outCS;
            }
            if(col2[i-1]=='U') {
                NWF::addEdge(i+n1,CT, inf, 0);
                NWF::addEdge(CS,i+n1, inf, 0);
            }
        }
        NWF::addEdge(CT, CS, inf, 0);
        NWF::addEdge(NWF::S, CT, inCT, 0);
        NWF::addEdge(CS, NWF::T, outCS, 0);
        for(int i = 1, u, v; i <= m; i++) {
            cin >> u >> v; v += n1;
            NWF::addEdge(u, v, 1, r);
            NWF::addEdge(v, u, 1, b);
            msk[i] = NWF::ecnt - 3;
        }
        LL ans = NWF::mcmf();
        if(NWF::check()) cout << "-1" <<endl;
        else{
            cout << ans << endl;
            for(int i = 1; i <= m; i++)
                cout << (NWF::e[msk[i]].f == 0 ?'R': NWF::e[msk[i]+2].f==0?'B':'U');
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    博客园定制
    【杂文】久 等 了
    【杂文】随心一记
    NOIP2021游寄
    【python】mac+appium+python的环境配置完整流程
    压力测试平台(nGrinder)入门到精通教程
    Gunicorn启动flask项目
    统计代码测试覆盖率Python
    Android开发Google Pixel、Google Nexus系列手机刷机获取root并且设置ro.debuggable=1的方法
    c宏定义#define、#、##、__VA_ARGS__符号的理解
  • 原文地址:https://www.cnblogs.com/hjj1871984569/p/12235383.html
Copyright © 2020-2023  润新知