zoukankan      html  css  js  c++  java
  • [NOI2008]志愿者招募

    题面

    link

    分析

    看到要求每天最少a[i]人 那么就反过来
    使流量最大为inf - a[i]
    因为是以天来限制人数 所以每天作为一条边
    S --inf / 0 --> 第一天的起点 node[1]
    最后一天终点 node[n + 1] -- inf / 0 --> T
    第i天: node[i] -- inf / a[i] --> node[i + 1]

    志愿者是补流 为了使最大流为inf
    那么使node[s[i]] -- inf / c[i] --> node[t[i] + 1]
    跑最小费用最大流即可

    // luogu-judger-enable-o2
    #include <bits/stdc++.h>
    using namespace std;
    /*
    建图:S --inf / 0 --> 第一天的起点 node[1]
    最后一天终点  node[n + 1] -- inf / 0 --> T
    第i天:  node[i] -- inf / a[i] --> node[i + 1]
    志愿者是补流 为了使最大流为inf 
    那么使node[s[i]] -- inf / c[i] --> node[t[i] + 1]
    */
    #define node(x, y) n + (x - 1) * ptot + (y)
    typedef long long ll;
    const ll inf = 1e11;
    const int N = 1e3 + 5;
    const int E = 1e6; 
    struct Edge{
        int v, next; ll f, w;
    }edge[E];
    int esize = 1, head[N], S, T, n, m;
    ll mxf, mc;
    int fro, pre[N]; 
    ll dis[N], fl[N], p[45];
    queue<int> que;
    
    inline void addedge(int x, int y, ll f, ll w){
        edge[++esize] = (Edge){y, head[x], f, w}, head[x] = esize;
        edge[++esize] = (Edge){x, head[y], 0, -w}, head[y] = esize;
        //printf("%d %d %lld %lld
    ", x, y, f, w);
    }
    
    inline bool spfa(){
        for(int i = 1; i <= T; ++i) dis[i] = inf;
        que.push(S), dis[S] = 0, fl[S] = inf;
        while(!que.empty()){
            fro = que.front(), que.pop();
            for(int i = head[fro], vv; ~i; i = edge[i].next){
                vv = edge[i].v;
                if(edge[i].f > 0 && dis[vv] > dis[fro] + edge[i].w)
                    dis[vv] = dis[fro] + edge[i].w, pre[vv] = i, fl[vv] = min(edge[i].f, fl[fro]), que.push(vv);
            }
        }
        return dis[T] != inf;
    }
    
    inline void update(){
        int i = T, j;
        while(i != S){
            j = pre[i], edge[j].f -= fl[T], 
    		edge[j ^ 1].f += fl[T], i = edge[j ^ 1].v;
        } 
        mxf += fl[T], mc += fl[T] * dis[T];
    } 
    
    void EK(){
        while(spfa()) update();
    }
    
    int main(){
        memset(head, -1, sizeof(head));
        scanf("%d%d", &n, &m);
        S = n + 2, T = n + 3;//! 
        for(int i = 1, x; i <= n; ++i)
        	scanf("%d", &x), addedge(i, i + 1, inf - x, 0); 
        addedge(S, 1, inf, 0), addedge(n + 1, T, inf, 0);
        for(int i = 1, x, y, z; i <= m; ++i)
        	scanf("%d%d%d", &x, &y, &z), addedge(x, y + 1, inf, z);
        EK();
        printf("%lld", mc);
        return 0; 
    }
    
    
  • 相关阅读:
    eclipse中Preferences的一些设置
    eclipse中文乱码问题解决方案
    classpath、path、JAVA_HOME的作用
    java中抽象类与接口中方法访问修饰符问题 (
    Tomcat配置
    编译型语言和解释型语言
    强类型语言和弱类型语言
    javascript生成指定范围的随机整数
    java中int和Integer的区别
    红黑树入门
  • 原文地址:https://www.cnblogs.com/hjmmm/p/11281325.html
Copyright © 2011-2022 走看看