首页 > 代码库 > [BZOJ 1834][ZJOI2010]network 网络扩容(费用流)

[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 0x3f3f3f3fusing 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;}

 

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