zoukankan      html  css  js  c++  java
  • bzoj1061: [Noi2008]志愿者招募

    传送门

    线性规划,最小费用最大流。做法同学姐的逛街计划。

    设第i天要工作的志愿者为a[i][],第i类志愿者的数量为c[i],可以列出式子

    c[a[1][1]] + c[a[1][2]] + ……<=A[1]

    c[a[2][1]] + c[a[2][2]] + ……<=A[2]

    ……

    c[a[n][1]] + c[a[n][2]] + ……<=A[n]

    加上辅助变量y,前后加入两个0式:

    0 = 0                                                               (1)

    c[a[1][1]] + c[a[1][2]] + ……=A[1] + y[1]           (2)

    c[a[2][1]] + c[a[2][2]] + ……=A[2] + y[2]           (3)

    ……

    c[a[n][1]] + c[a[n][2]] + ……=A[n] + y[n]            (n+1)

    0 = 0                                                                  (n+2)

    差分:

    c[ ] + c[ ] + ……=A[1] + y[1]                               (1)

    c[ ] + c[ ] + ……=A[2] + y[2] - A[1] - y[1]            (2)

    ……

    c[ ] + c[ ] + ……=A[n] + y[n] - A[n-1] - y[n-1]         (n)

    c[ ] + c[ ] + ……=- A[n] - y[n]                               (n+1)

    容易看出对于A和y移项之后左右各出现了一次。

    而左边一的坨c,因为每种志愿者工作的时间是连续的一段l,r,那么差分后l+1~r都消去了c,只有l式出现 + c ,r+1式出现-c。

    移项后c也左右各出现了一次。

    于是用和之前一样的建图方法就好了。

    //Achen
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<ctime>
    #include<cmath>
    #define inf 1e18
    const int N=100007;
    typedef long long LL;
    using namespace std;
    int n,m,in[N]; 
    
    template<typename T> void read(T &x) {
        char ch=getchar(); x=0; T f=1;
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    struct edge {
        int u,v,nx;
        LL fl,cap,cost;
        edge(){}
        edge(int u,int v,LL fl,LL cap,LL cost,int nx):u(u),v(v),fl(fl),cap(cap),cost(cost),nx(nx){} 
    }e[N]; 
    
    int fir[N],ecnt=1;
    void add(int u,int v,LL cap,LL cost) {
        e[++ecnt]=edge(u,v,0,cap,cost,fir[u]); fir[u]=ecnt;
        e[++ecnt]=edge(v,u,0,0,-cost,fir[v]); fir[v]=ecnt;
    }
    
    int vis[N],p[N];
    LL dis[N];
    queue<int>que;
    int spfa(int s,int t) {
        for(int i=1;i<=n;i++) vis[i]=0,dis[i]=inf;
        que.push(s); dis[s]=0;
        while(!que.empty()) {
            int x=que.front();
            que.pop(); vis[x]=0;
            for(int i=fir[x];i;i=e[i].nx) 
            if(e[i].cap>e[i].fl) {
                int y=e[i].v;
                if(dis[y]>dis[x]+e[i].cost) {
                    dis[y]=dis[x]+e[i].cost;
                    p[y]=i; 
                    if(!vis[y]) {
                        vis[y]=1;
                        que.push(y);
                    }
                }
            }
        }
        return dis[t]!=inf;
    }
    
    LL calc(int s,int t) {
        LL fl=inf,res=0;
        for(int i=t;i!=s;i=e[p[i]].u) 
            fl=min(fl,e[p[i]].cap-e[p[i]].fl),
            res+=e[p[i]].cost;
        for(int i=t;i!=s;i=e[p[i]].u) 
            e[p[i]].fl+=fl,e[p[i]^1].fl-=fl;
        return fl*res;
    } 
    
    LL max_flow(int s,int t) {
        LL res=0;
        while(spfa(s,t)) 
            res+=calc(s,t);
        return res;
    }
    
    int main() {
        read(n); read(m);
        int s=n+2,t=s+1;
        for(int i=1;i<=n;i++) {
            int A; read(A);
            in[i]+=A; in[i+1]-=A;
        }
        for(int i=1;i<=n+1;i++) {
            if(in[i]>=0) add(s,i,in[i],0);
            else add(i,t,-in[i],0);
            if(i>1) add(i,i-1,inf,0);
        }
        for(int i=1;i<=m;i++) {
            int l,r,c;
            read(l); read(r); read(c);
            add(l,r+1,inf,c);
        }
        n=t;
        LL ans=max_flow(s,t);
        printf("%lld
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    kendoui仪表盘和柱状图 示例
    log4net修改数据库连接字符串和写自定义信息
    为sharepoint的内部页面添加后台代码
    Qt中对QDomDocument和QDomnode的理解
    标准输出中stderr和stdout的区别
    设计一个算法移除字符串中的重复字符,并写出测试用例。
    字符串中单词的逆转,即将单词出现的顺序进行逆转。如将“Today is Friday!”逆转为“Friday! is Today”.
    输入两个很大的正数(用C字符串表示),输出他们的乘积,将设不考虑非法输入。
    微信公众平台的开发过程及其要点
    NR_OPEN 与 NR_FILE 的区别
  • 原文地址:https://www.cnblogs.com/Achenchen/p/8400612.html
Copyright © 2011-2022 走看看