[BZOJ 1834][ZJOI2010]network 网络扩容(费用流)

Description

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

Solution

先求出最大流maxflow

求最小扩容费用的话,对于每一条边,建一条容量为c费用为0的边,再建一条容量为INF费用为w的边

跑费用流求流入maxflow+k的费用

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstdlib>
#include<cstring>
#define INF 0x3f3f3f3f
using namespace std;
int s,t,n,m,k,head[1005],cnt=0,a[1005],dis[1005],pre[1005];
int flow,cost;
bool inq[1005];
int read()
{
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-')f=-1;c=getchar();
    }
    while(c>='0'&&c<='9'){
        x=x*10+c-'0';c=getchar();
    }
    return x*f;
}
struct Node
{
    int next,from,to,cap,w;
}Edges[20005];
void addedge(int u,int v,int c,int w)
{
    Edges[cnt].next=head[u];
    head[u]=cnt;
    Edges[cnt].from=u;
    Edges[cnt].to=v;
    Edges[cnt].cap=c;
    Edges[cnt].w=w;
    cnt++;
}
void insert(int u,int v,int c,int w)
{
    addedge(u,v,c,w);
    addedge(v,u,0,-w);
}
queue<int>q;
void MCMF(int x)
{
    flow=0,cost=0;
    while(1)
    {
        memset(a,0,sizeof(a));
        memset(dis,0x3f,sizeof(dis));
        q.push(s);
        pre[s]=-1;dis[s]=0,a[s]=x?x-flow:INF,inq[s]=1;
        while(!q.empty())
        {
            int u=q.front();
            q.pop(),inq[u]=0;
            for(int i=head[u];~i;i=Edges[i].next)
            {
                int v=Edges[i].to;
                if(!x&&Edges[i].cap==INF)continue;
                if(dis[v]>dis[u]+Edges[i].w&&Edges[i].cap>0)
                {
                    dis[v]=dis[u]+Edges[i].w;
                    a[v]=min(a[u],Edges[i].cap);
                    pre[v]=i;
                    if(!inq[v]){q.push(v);inq[v]=1;}
                    
                }
            }
        }
        if(a[t]==0)break;
        flow+=a[t];
        int p=t;
        cost+=a[t]*dis[t];
        while(pre[p]!=-1)
        {
            Edges[pre[p]].cap-=a[t];
            Edges[pre[p]^1].cap+=a[t];
            p=Edges[pre[p]].from;
        }
    }
}
int main()
{
    memset(head,-1,sizeof(head));
    n=read(),m=read(),k=read();
    s=1,t=n;
    for(int i=1;i<=m;i++)
    {
        int u=read(),v=read(),c=read(),w=read();
        insert(u,v,c,0);
        insert(u,v,INF,w);
    }
    MCMF(0);
    printf("%d ",flow);
    MCMF(k);
    printf("%d\n",cost);
    return 0;
}

 

posted @ 2017-05-17 12:30  Zars19  阅读(214)  评论(0编辑  收藏  举报