码迷,mamicode.com
首页 > Web开发 > 详细

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

时间:2017-05-17 14:13:59      阅读:222      评论:0      收藏:0      [点我收藏+]

标签:name   insert   namespace   cap   continue   font   get   main   color   

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;
}

 

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

标签:name   insert   namespace   cap   continue   font   get   main   color   

原文地址:http://www.cnblogs.com/Zars19/p/6866979.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!