zoukankan      html  css  js  c++  java
  • P3980 [NOI2008]志愿者招募 费用流 (人有多大胆地有多大产

    感觉费用流比网络流的图更难想到,要更大胆。
    首先由于日期是连续的,所以图中的点是横向排列的。

    这道题有点绕道走的意思,由于一类志愿者是可以服务于一段时间,那我们给第i天连出去多条边,第一条边是流向i+1点的,容量为inf-a【i】,费用为0,
    若有i 到 其他点t,费用为w, 则连一条(i, t+1, inf,w)的边

    跑一遍费用流,算出结果

    #include <algorithm>
    #include  <iterator>
    #include  <iostream>
    #include   <cstring>
    #include   <cstdlib>
    #include   <iomanip>
    #include    <bitset>
    #include    <cctype>
    #include    <cstdio>
    #include    <string>
    #include    <vector>
    #include     <stack>
    #include     <cmath>
    #include     <queue>
    #include      <list>
    #include       <map>
    #include       <set>
    #include   <cassert>
    
    /*
            
    ⊂_ヽ
      \\ Λ_Λ  来了老弟
       \('ㅅ')
        > ⌒ヽ
       /   へ\
       /  / \\
       レ ノ   ヽ_つ
      / /
      / /|
     ( (ヽ
     | |、\
     | 丿 \ ⌒)
     | |  ) /
    'ノ )  Lノ
    
    */
    
    using namespace std;
    #define lson (l , mid , rt << 1)
    #define rson (mid + 1 , r , rt << 1 | 1)
    #define debug(x) cerr << #x << " = " << x << "
    ";
    #define pb push_back
    #define pq priority_queue
    
    
    
    typedef long long ll;
    typedef unsigned long long ull;
    //typedef __int128 bll;
    typedef pair<ll ,ll > pll;
    typedef pair<int ,int > pii;
    typedef pair<int,pii> p3;
    
    //priority_queue<int> q;//这是一个大根堆q
    //priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
    #define fi first
    #define se second
    //#define endl '
    '
    
    #define boost ios::sync_with_stdio(false);cin.tie(0)
    #define rep(a, b, c) for(int a = (b); a <= (c); ++ a)
    #define max3(a,b,c) max(max(a,b), c);
    #define min3(a,b,c) min(min(a,b), c);
    
    
    const ll oo = 1ll<<17;
    const ll mos = 0x7FFFFFFF;  //2147483647
    const ll nmos = 0x80000000;  //-2147483648
    const int inf = 0x3f3f3f3f;
    const ll inff = 0x3f3f3f3f3f3f3f3f; //18
    const ll mod = 2147483648;
    const double esp = 1e-8;
    const double PI=acos(-1.0);
    const double PHI=0.61803399;    //黄金分割点
    const double tPHI=0.38196601;
    
    
    template<typename T>
    inline T read(T&x){
        x=0;int f=0;char ch=getchar();
        while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
        while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
        return x=f?-x:x;
    }
    
    inline void cmax(int &x,int y){if(x<y)x=y;}
    inline void cmax(ll &x,ll y){if(x<y)x=y;}
    inline void cmin(int &x,int y){if(x>y)x=y;}
    inline void cmin(ll &x,ll y){if(x>y)x=y;}
    
    /*-----------------------showtime----------------------*/
                
                const int maxn = 1e3+9;
                int a[maxn];
                struct E{
                    int v,val,cost;
                    int nxt;
                }edge[maxn*maxn];
                int head[maxn],gtot;
                void addedge(int u,int v,int val,int cost){
                    edge[gtot].v = v;
                    edge[gtot].val = val;
                    edge[gtot].cost = cost;
                    edge[gtot].nxt = head[u];
                    head[u] = gtot++;
    
                    edge[gtot].v = u;
                    edge[gtot].val = 0;
                    edge[gtot].cost = -cost;
                    edge[gtot].nxt = head[v];
                    head[v] = gtot++;
                }
    
                int dis[maxn],pre[maxn],vis[maxn],path[maxn];
                bool spfa(int s,int t){
                    memset(dis,inf, sizeof(dis));
                    memset(vis, 0, sizeof(vis));
                    memset(pre, -1, sizeof(pre));
    
                    dis[s] = 0; vis[s] = 1;
                    queue<int>que;
                    que.push(s);
    
                    while(!que.empty()){
                        int u = que.front(); que.pop();
                        vis[u] = 0;
                        for(int i=head[u]; ~i; i=edge[i].nxt){
                            int v = edge[i].v, val = edge[i].val, cost = edge[i].cost;
                            if(val > 0 && dis[v] > dis[u] + cost){
                                dis[v] = dis[u] + cost;
                                pre[v] = u; path[v] = i;
                                if(vis[v] == 0){
                                    vis[v] = 1;
                                    que.push(v);
                                }
                            }
                        }
                    }
                    return pre[t] != -1;
                }
                int mcmf(int s,int t){
                    int flow = 0, cost = 0;
                    while(spfa(s, t)){
                        int f = inf;
                        for(int i=t; i!=s; i=pre[i]){
                            f = min(f, edge[path[i]].val);
                        }
                        flow += f;
                        cost += f * dis[t];
                        for(int i=t; i!=s; i=pre[i]){
                            edge[path[i]].val -= f;
                            edge[path[i]^1].val += f;
                        }
                    }
                    return cost;
                }
    int main(){
                memset(head, -1, sizeof(head));
                int n,m;    
                scanf("%d%d", &n, &m);
                rep(i, 1, n) scanf("%d", &a[i]);
                int s = 0, t = n+2;
                addedge(s, 1, inf, 0);
                addedge(n+1, t, inf, 0);
                rep(i, 1, n) addedge(i, i+1, inf - a[i], 0);
                
                while(m --) {
                    int u,v,w;
                    scanf("%d%d%d", &u, &v, &w);
                    addedge(u, v+1, inf, w);
                }
                printf("%d
    ", mcmf(s, t));
                
                return 0;
    }
    View Code
  • 相关阅读:
    Balanced Binary Tree
    Swap Nodes in Pairs
    Reverse Nodes in k-Group
    Reverse Linked List II
    Remove Nth Node From End of List
    Remove Duplicates from Sorted List II
    Remove Duplicates from Sorted List
    Partition List
    Merge Two Sorted Lists
    【Yii2.0】1.2 Apache检查配置文件语法
  • 原文地址:https://www.cnblogs.com/ckxkexing/p/10404094.html
Copyright © 2011-2022 走看看