zoukankan      html  css  js  c++  java
  • BZOJ 1834 [ZJOI2010]network 网络扩容(费用流)

    【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=1834

    【题目大意】

      给定一张有向图,每条边都有一个容量C和一个扩容费用W。
      这里扩容费用是指将容量扩大1所需的费用。求:
        1.在不扩容的情况下,1到N的最大流;
        2.将1到N的最大流增加K所需的最小扩容费用。

    【题解】

      对于第一问,直接计算最大流即可,对于第二问,在最大流的残余网络上
      对于每条边建立费用为w容量无限的边,跑1到N的流量大小为k的费用流即可。

    【代码】

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cstring> 
    #include <queue>
    using namespace std;
    const int INF=0x3f3f3f3f;
    struct edge{int to,cap,cost,rev;};
    const int MAX_V=10000;
    int V,dist[MAX_V],prevv[MAX_V],preve[MAX_V];
    int level[MAX_V],iter[MAX_V];
    vector<edge> G[MAX_V];
    void add_edge(int from,int to,int cap,int cost){
        G[from].push_back((edge){to,cap,cost,G[to].size()});
        G[to].push_back((edge){from,0,-cost,G[from].size()-1});
    }
    void bfs(int s){
        memset(level,-1,sizeof(level));
        queue<int> que;
        level[s]=0;
        que.push(s);
        while(!que.empty()){
            int v=que.front(); que.pop();
            for(int i=0;i<G[v].size();i++){
                edge &e=G[v][i];
                if(e.cap>0&&level[e.to]<0){
                    level[e.to]=level[v]+1;
                    que.push(e.to);
                }
            }
        }
    }
    int dfs(int v,int t,int f){
        if(v==t)return f;
        for(int &i=iter[v];i<G[v].size();i++){
            edge &e=G[v][i];
            if(e.cap>0&&level[v]<level[e.to]){
                int d=dfs(e.to,t,min(f,e.cap));
                if(d>0){
                    e.cap-=d;
                    G[e.to][e.rev].cap+=d;
                    return d;
                }
            }
        }return 0;
    }
    int max_flow(int s,int t){
        int flow=0;
        for(;;){
            bfs(s);
            if(level[t]<0)return flow;
            memset(iter,0,sizeof(iter));
            int f;
            while((f=dfs(s,t,INF))>0){
                flow+=f;
            }
        }
    }
    int min_cost_flow(int s,int t,int f){
        int res=0;
        while(f>0){
            fill(dist,dist+V,INF);
            dist[s]=0;
            bool update=1;
            while(update){
                update=0;
                for(int v=0;v<V;v++){
                    if(dist[v]==INF)continue;
                    for(int i=0;i<G[v].size();i++){
                        edge &e=G[v][i];
                        if(e.cap>0&&dist[e.to]>dist[v]+e.cost){
                            dist[e.to]=dist[v]+e.cost;
                            prevv[e.to]=v;
                            preve[e.to]=i;
                            update=1;
                        }
                    }
                }
            }
            if(dist[t]==INF)return -1;
            int d=f;
            for(int v=t;v!=s;v=prevv[v]){
                d=min(d,G[prevv[v]][preve[v]].cap);
            }f-=d;
            res+=d*dist[t];
            for(int v=t;v!=s;v=prevv[v]){
                edge &e=G[prevv[v]][preve[v]];
                e.cap-=d;
                G[v][e.rev].cap+=d; 
            }
        }return res;
    }
    void clear(){for(int i=0;i<V;i++)G[i].clear();}
    int N,M,K;
    int cas=0,a[5010],b[5010],c[5010],w[5010];
    void solve(){
        V=N+1; clear();
        for(int i=1;i<=M;i++)add_edge(a[i],b[i],c[i],0);
        printf("%d ",max_flow(1,N));
        for(int i=1;i<=M;i++)add_edge(a[i],b[i],INF,w[i]);
        printf("%d
    ",min_cost_flow(1,N,K));
    }
    int main(){
        while(~scanf("%d%d%d",&N,&M,&K)){
            for(int i=1;i<=M;i++)scanf("%d%d%d%d",&a[i],&b[i],&c[i],&w[i]);
            solve();
        }return 0;
    }
  • 相关阅读:
    SQL Server 2005 中 Cross join & Cross Apply & Outer Apply 的区别
    How to install Database using commandline prompt
    Get SQL Server default collation
    Shrink DB and Log
    Visual C++ Debugging: Why does program work in debug mode, but fail in release mode?
    使用Windows的SHFileOperation外壳函数实现文件操作
    2 types of C++ compiler guards
    LUA中的基本函数库
    Ruby 数组操作方法(转)
    ruby中的yield的概念
  • 原文地址:https://www.cnblogs.com/forever97/p/bzoj1834.html
Copyright © 2011-2022 走看看