首页 > 代码库 > [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 网络扩容(费用流)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。