• [NOI2008] 志愿者招募


    (i) 点表示第 (i)

    志愿者 ((s_i,t_i,c_i)),建边 (s_i o t_i +1),费用 (c_i),流量无限

    (i)(i+1) 连边 (inf - a[i]),费用为(0)

    (S o 1, n+1 o T),费用为 (0),容量 (inf)

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    
    namespace mcmf {
    const int maxn = 50005;
    const int maxm = 300005;
    const int inf = 1e+9;
    struct R {
        int to, nxt, co, va;
    } e[maxm * 2 + 5];
    int q[maxm + 5], l, r;
    int vs[maxn + 5], nxt[maxn + 5], d[maxn + 5];
    int h[maxn + 5], cnt = 1;
    int n, m;
    int ans;
    void add(int u, int v, int w, int c) {
        cnt++;
        e[cnt] = (R){ v, h[u], w, c };
        h[u] = cnt;
        return;
    }
    int Spfa(int s, int t) {
        for (int i = 1; i <= n; i++) {
            nxt[i] = -1;
            d[i] = inf;
            vs[i] = 0;
        }
        l = r = 1;
        q[l] = s;
        d[s] = 0;
        vs[s] = 1;
        while (l <= r) {
            int u = q[l];
            l++;
            vs[u] = 0;
            for (int i = h[u]; i; i = e[i].nxt) {
                int v = e[i].to;
                int w = e[i].va;
                if (e[i].co && d[u] + w < d[v]) {
                    nxt[v] = i;
                    d[v] = d[u] + w;
                    if (!vs[v]) {
                        q[++r] = v;
                        vs[v] = 1;
                    }
                }
            }
        }
        if (d[t] < inf)
            return 1;
        return 0;
    }
    void Mco(int s, int t) {
        int flow = 0, cost = 0;
        while (Spfa(s, t)) {
            //cout<<"!";
            int mn = inf;
            for (int p = nxt[t]; p != -1; p = nxt[e[p ^ 1].to]) mn = min(e[p].co, mn);
            for (int p = nxt[t]; p != -1; p = nxt[e[p ^ 1].to]) {
                e[p].co -= mn;
                e[p ^ 1].co += mn;
            }
            flow += mn;
            cost += mn * d[t];
            //cout<<"?";
        }
        ans = cost;
        //cout<<flow<<endl;
        return;
    }
    }
    
    const int N = 50005;
    const int inf = 1e+9;
    
    int n,m;
    
    void mk(int u,int v,int w,int c) {
        //cout<<u<<" "<<v<<" "<<w<<" "<<c<<endl;
        mcmf::add(u,v,w,c);
        mcmf::add(v,u,0,-c);
    }
    
    int s[N],t[N],c[N],a[N];
    
    signed main() {
        cin>>n>>m;
        for(int i=1;i<=n;i++) cin>>a[i], mk(i,i+1,inf-a[i],0);
        mcmf::n = n+3;
        mk(n+2,1,inf,0);
        mk(n+1,n+3,inf,0);
        for(int i=1;i<=m;i++) {
            cin>>s[i]>>t[i]>>c[i];
            mk(s[i],t[i]+1,inf,c[i]);
        }
        mcmf::Mco(n+2,n+3);
        cout<<mcmf::ans<<endl;
    }
    
  • 相关阅读:
    第6课.内联函数分析
    第5课.引用的本质分析
    第4课.布尔类型和引用
    第3课.进化后的const
    第2课.C到C++的升级
    c语言深度解剖(笔记)
    你必须知道的495个c语言问题(笔记)
    JS弹出框
    车牌号正则表达式
    input输入文字后背景色变成了黄色 CSS改变(去掉黄色背景)
  • 原文地址:https://www.cnblogs.com/mollnn/p/12272064.html
Copyright © 2020-2023  润新知