• bzoj 1061: [Noi2008]志愿者招募


    /*
        题目大意:
            项目需要N 天才能完成,其中第i 天至少需要Ai 个人。 布布通过了解得知,一共有M 类志愿者可以招募。其中第i 类可以从第Si 天工作到第Ti 天,招募费用是每人Ci 元。新官上任三把火,为了出色地完成自己的工作,布布希望用尽量少的费用招募足够的志愿者 
        题解:
            http://blog.csdn.net/lych_cys/article/details/50703729 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #define INF 1e9
    #define maxn 10010
    using namespace std;
    int n,m,head[maxn],num=1,a[maxn],S,T,ans,dis[maxn];
    bool mark[maxn],vis[maxn];
    struct node{int to,pre,c,cc;}e[maxn*10];
    void Insert(int from,int to,int c,int cc){
        e[++num].to=to;
        e[num].c=c;
        e[num].cc=cc;
        e[num].pre=head[from];
        head[from]=num;
    }
    bool spfa(){
        queue<int>q;
        q.push(T);
        for(int i=S;i<=T;i++)vis[i]=0,dis[i]=INF;
        vis[T]=1;dis[T]=0;
        while(!q.empty()){
            int now=q.front();q.pop();vis[now]=0;
            for(int i=head[now];i;i=e[i].pre){
                int to=e[i].to;
                if(dis[to]>dis[now]-e[i].cc&&e[i^1].c){
                    dis[to]=dis[now]-e[i].cc;  
                    if(!vis[to])vis[to]=1,q.push(to);
                }
            }
        }
        return dis[S]!=INF;
    }
    int dfs(int now,int flow){
        mark[now]=1;
        if(now==T)return flow;
        int delta,used=0;
        for(int i=head[now];i;i=e[i].pre){
            int to=e[i].to;
            if(e[i].c&&!mark[to]&&dis[to]==dis[now]-e[i].cc){
                delta=dfs(to,min(flow-used,e[i].c));
                ans+=delta*e[i].cc;
                used+=delta;
                e[i].c-=delta;e[i^1].c+=delta;
                if(used==flow)return used;
            }
        }
        return used;
    }
    void solve(){
        int tmp=0;
        while(spfa()){
            mark[T]=1;
            while(mark[T]){
                memset(mark,0,sizeof(mark));
                tmp+=dfs(S,INF);
            }
        }
    }
    int main(){
        scanf("%d%d",&n,&m);
        S=0,T=1005;
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            int cha=a[i]-a[i-1];
            if(cha>0)Insert(S,i,cha,0),Insert(i,S,0,0);
            else Insert(i,T,-cha,0),Insert(T,i,0,0);
            Insert(i+1,i,INF,0),Insert(i,i+1,0,0);
        }
        Insert(n+1,T,a[n],0);Insert(T,n+1,0,0);
        int l,r,C;
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&l,&r,&C);
            Insert(l,r+1,INF,C);Insert(r+1,l,0,-C);
        }
        solve();
        printf("%d",ans);
        return 0;
    } 
  • 相关阅读:
    如何为Android写一个PhoneGap插件
    Javascript高性能动画与页面渲染
    jquery mobile Popup
    android学习资料免费下载
    锋利的jquery第2版高清 pdf
    android获取sd卡最后一张照片
    mongodb 基础
    django 实现读写分离
    docker 部署django方式
    mysql 主从读写
  • 原文地址:https://www.cnblogs.com/thmyl/p/8409927.html
Copyright © 2020-2023  润新知