標籤: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 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 網路擴容(費用流)