zoukankan      html  css  js  c++  java
  • 【BZOJ1834】 网络扩容

     

    Time Limit: 1000 ms   Memory Limit: 128 MB

    Description

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

    Input

      输入文件的第一行包含三个整数N,M,K,表示有向图的点数、边数以及所需要增加的流量。 接下来的M行每行包含四个整数u,v,C,W,表示一条从u到v,容量为C,扩容费用为W的边。

    Output

      输出文件一行包含两个整数,分别表示问题1和问题2的答案。

    Sample Input

      5 8 2
      1 2 5 8
      2 5 9 9
      5 1 6 2
      5 1 1 8
      1 2 8 7
      2 5 4 9
      1 2 1 1
      1 4 2 1

    Sample Output

      13 19

      30%的数据中,N<=100
      100%的数据中,N<=1000,M<=5000,K<=10
     

    Solution

      第一问直接上裸SPFA最大流,对于输入每条边$(u,v,f,c)$,流量设为输入的$f$,而费用设为0。(EK)

      对于第二问,考虑第一问完成后的残余网络。对于残余网络上的每一条边,理应都可以0费用扩容;而残余网络上不存在的边,扩容就需要$w$(反向弧为$-w$)。

      那么直接在第一问跑完后的残余网络上建图,对于输入的每一条边$(u,v,f,c)$,流量设为$+infty$,费用设为$w$(反向弧$-w$)。

      这样在两种边下跑费用流,会优先选择原来残余网络上费用为$0$的边来增广,那么0费用扩容的边刻画完成;其他的边需要付出费用的,也可以体现。

      最后,由$n$连向一个超级汇点$T$,流量为$k$,费用为$0$,跑费用流即可。

     


      

    #include <cstdio>
    #include <queue>
    using namespace std;
    const int N=1010,M=5010,INF=2147000000;
    int n,m,k,tot=1,e[M][4],h[N];
    int S,T,dis[N],inq[N],pre[N],which[N];
    struct Edge{int v,f,c,next;}g[M*4];
    queue<int> q;
    inline void addEdge(int u,int v,int f,int c=0){
        g[++tot].v=v; g[tot].f=f; g[tot].c=c; g[tot].next=h[u]; h[u]=tot;
        g[++tot].v=u; g[tot].f=0; g[tot].c=-c; g[tot].next=h[v]; h[v]=tot;
    }
    bool spfa(){
        while(!q.empty()) q.pop();
        q.push(S);
        for(int i=1;i<=T;i++) dis[i]=INF,inq[i]=pre[i]=0;
        dis[S]=0; inq[S]=1;
        while(!q.empty()){ 
            int u=q.front(); q.pop();
            for(int i=h[u],v;i;i=g[i].next)
                if(g[i].f&&dis[u]+g[i].c<dis[v=g[i].v]){
                    dis[v]=dis[u]+g[i].c;
                    which[v]=i;
                    pre[v]=u;
                    if(!inq[v]){
                        inq[v]=1;
                        q.push(v);
                    }
                }
            inq[u]=0;
        }
        return dis[T]!=INF;
    }
    int solve(int type){
        int mins,maxflow=0,mincost=0;
        while(spfa()){
            mins=INF;
            for(int u=T;u!=S;u=pre[u])
                if(g[which[u]].f<mins)
                    mins=g[which[u]].f;
            maxflow+=mins; mincost+=mins*dis[T];
            for(int u=T;u!=S;u=pre[u]){
                g[which[u]].f-=mins;
                g[which[u]^1].f+=mins;
            }
        }
        return !type?maxflow:mincost;
    }
    int main(){
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=m;i++){
            scanf("%d%d%d%d",&e[i][0],&e[i][1],&e[i][2],&e[i][3]);
            addEdge(e[i][0],e[i][1],e[i][2]);
        }
        S=1; T=n;
        printf("%d ",solve(0));
        T=n+1;
        addEdge(n,T,k,0);
        for(int i=1;i<=m;i++)
            addEdge(e[i][0],e[i][1],INF,e[i][3]);
        printf("%d
    ",solve(1));
    }
    奇妙代码
  • 相关阅读:
    WinAPI: midiOutReset 重置输出设备
    WinAPI: midiOutLongMsg 向输出设备发送一条系统专用的 MIDI 消息
    WinAPI: midiInStart 启动输入
    WinAPI: midiOutClose 关闭输出设备
    WinAPI: midiInStop 停止输入
    bootstrap居中
    设计模式之访问者模式
    zend framework 开发环境搭建及入门
    转:GIT GUI使用
    Asp web.config详解
  • 原文地址:https://www.cnblogs.com/RogerDTZ/p/8021434.html
Copyright © 2011-2022 走看看