BZOJ 1834--網絡擴容(最大流&費用流)
阿新 • • 發佈:2017-10-28
最大 oid his 最小 http space getch include size
值得一做的好題。。。
題目鏈接:
http://www.lydsy.com/JudgeOnline/problem.php?id=1834
Solution
第一問是赤果果的最大流。。。上模板就好。。。
然後問擴流的最小費用。。。發現可以直接利用之前跑完最大流剩下的殘余網絡。
在每一條邊上額外加一條容量無限大的邊,但是這樣不能控制流的大小,所以要額外添加一個匯點S。
從S向原起點連一條容量為k的邊,再跑一遍費用流,就是第二問的答案。。。
代碼
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<iostream> #define N 1010 #define inf 2000000000 using namespace std; inline int Read(){ int x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } int n,m,k,ans=0,cnt=1,S,T; int hed[N],dis[N],l[N],q[200000]; bool vis[N]; struct edge{ int l,r,nxt,v,c,t; }e[50000]; void insert(int u,int v,int w,int c){ cnt++;e[cnt].l=u;e[cnt].r=v;e[cnt].nxt=hed[u];hed[u]=cnt;e[cnt].v=w;e[cnt].c=0;e[cnt].t=c; cnt++;e[cnt].l=v;e[cnt].r=u;e[cnt].nxt=hed[v];hed[v]=cnt;e[cnt].v=0;e[cnt].c=0;e[cnt].t=-c; } bool BFS(){ int head=0,tail=1,now; memset(dis,-1,sizeof(dis)); dis[S]=1;q[1]=S; while(head!=tail){ head++; now=q[head]; for(int i=hed[now];i;i=e[i].nxt) if(e[i].v && dis[e[i].r]==-1){ dis[e[i].r]=dis[now]+1; q[++tail]=e[i].r; } } return dis[T]!=-1; } int DFS(int x,int F){ if(x==T)return F; int w,used=0; for(int i=hed[x];i;i=e[i].nxt) if(dis[e[i].r]==dis[x]+1){ w=F-used; if(w>e[i].v)w=e[i].v; w=DFS(e[i].r,w); e[i].v-=w; e[i^1].v+=w; used+=w; if(used==F)return F; } if(!used)dis[x]=-1; return used; } void dinic(){ while( BFS() ) ans+=DFS(S,inf); } void ins(int u,int v,int w,int c){ cnt++;e[cnt].l=u;e[cnt].r=v;e[cnt].v=w;e[cnt].nxt=hed[u];hed[u]=cnt;e[cnt].c=c; cnt++;e[cnt].l=v;e[cnt].r=u;e[cnt].v=0;e[cnt].nxt=hed[v];hed[v]=cnt;e[cnt].c=-c; } bool spfa(){ int head=0,tail=1,now; for(int i=0;i<=n;i++)dis[i]=inf; q[1]=S;dis[S]=0;vis[S]=1; while(head!=tail){ head++; now=q[head]; for(int i=hed[now];i;i=e[i].nxt) if(e[i].v>0 && dis[now]+e[i].c<dis[e[i].r]){ dis[e[i].r]=dis[now]+e[i].c; l[e[i].r]=i; if(!vis[e[i].r]){ tail++; q[tail]=e[i].r; vis[e[i].r]=1; } } vis[now]=0; } return dis[T]!=inf; } int mincf(){ int now,used=inf; now=l[T]; while(now){ if(used>e[now].v)used=e[now].v; now=l[e[now].l]; } now=l[T]; while(now){ e[now].v-=used; e[now^1].v+=used; ans+=used*e[now].c; now=l[e[now].l]; } } void Cost_Flow(){ while( spfa() ) ans+=mincf(); } int main(){ int u,v,w,c; n=Read();m=Read();k=Read(); S=1;T=n; for(int i=1;i<=m;i++){ u=Read();v=Read();w=Read();c=Read(); insert(u,v,w,c); } dinic(); printf("%d ",ans); ans=0; int tot=cnt; for(int i=2;i<=tot;i+=2) ins(e[i].l,e[i].r,inf,e[i].t); S=0; ins(0,1,k,0); Cost_Flow(); printf("%d\n",ans); return 0; }
This passage is made by Iscream-2001.
BZOJ 1834--網絡擴容(最大流&費用流)