[BZOJ1834]ZJOI2010网络扩容|最大流|费用流
2015-04-18 11:02
441 查看
差不多就是模板题嘛。。一开始先跑最大流不用多说,跑完后在残余网络上再建图,给每条原来边建一条流量无穷,费用为这条边扩容费用的边,再新建一个源点向1连流量为k费用0的边,跑费用流即可。。正确性貌似很显然。。
#include<iostream> #include<cstdio> #include<memory.h> #define maxn 1005 #define M 30005 #define inf 99999999 using namespace std; struct edge{ int s,e,next,f,q,t; }ed[M]; int i,n,m,k,s,e,f,q,ne=1,nd,head,tail,hh,tt,get,t,a[maxn],d[maxn],minf[maxn],inq[maxn],que[maxn*10],last[maxn],road[maxn],u[maxn]; void add1(int s,int e,int f,int q) { ed[++ne].s=s;ed[ne].e=e; ed[ne].f=f;ed[ne].q=0; ed[ne].t=q; ed[ne].next=a[s];a[s]=ne; } void add2(int s,int e,int f,int q) { ed[++ne].e=e; ed[ne].f=f;ed[ne].q=q; ed[ne].next=a[s];a[s]=ne; } bool bfs(int s,int t) { int i,j; memset(d,0,sizeof(d));memset(u,0,sizeof(u)); que[1]=s;head=tail=1;u[s]=1; while (head<=tail) { get=que[head++]; for (j=a[get];j;j=ed[j].next) { if(ed[j].f&&!u[ed[j].e]) { d[ed[j].e]=d[get]+1; u[ed[j].e]=1; que[++tail]=ed[j].e; } } } return d[t]!=0; } int extend(int x,int minf,int t) { int f=minf,j,del; if (x==t) return minf; for (j=a[x];j;j=ed[j].next) if (ed[j].f&&d[ed[j].e]==d[x]+1) { del=extend(ed[j].e,min(minf,ed[j].f),t); ed[j].f-=del;ed[j^1].f+=del; minf-=del; if (!minf) break; } if (f==minf) d[x]=0; return f-minf; } int dinic(int s,int t) { int ans=0; while (bfs(s,t)) ans+=extend(s,inf,t); return ans; } int spfa(int s,int t) { int i,j,to; for (i=0;i<=nd;i++) d[i]=inf,last[i]=road[i]=-1,inq[i]=0; head=tail=hh=tt=1;minf[s]=inf; que[1]=s;inq[s]=1;d[s]=0; while (hh<=tt) { get=que[head]; hh++;head++;if (head>10000) head=1; for (j=a[get];j;j=ed[j].next) if (ed[j].f&&ed[j].q+d[get]<d[ed[j].e]) { to=ed[j].e; d[to]=d[get]+ed[j].q; last[to]=get;road[to]=j; minf[to]=min(minf[get],ed[j].f); if (!inq[to]) { tail++;tt++;if (tail>10000) tail=1; que[tail]=to; inq[to]=1; } } inq[get]=0; } return last[t]!=-1; } int fyl(int s,int t) { int i,ans=0; while (spfa(s,t)) { ans+=d[t]*minf[t]; for (i=t;last[i]!=-1;i=last[i]) { ed[road[i]].f-=minf[t]; ed[road[i]^1].f+=minf[t]; } } return ans; } int main() { freopen("1834.in","r",stdin); scanf("%d%d%d",&n,&m,&k); memset(a,0,sizeof(a));nd=n; for (i=1;i<=m;i++) { scanf("%d%d%d%d",&s,&e,&f,&q); add1(s,e,f,q);add1(e,s,0,-q); } printf("%d ",dinic(1,n)); t=ne; for (i=2;i<=t;i+=2) add2(ed[i].s,ed[i].e,inf,ed[i].t),add2(ed[i].e,ed[i].s,0,-ed[i].t); add2(0,1,k,0);add2(1,0,0,0); printf("%d",fyl(0,n)); }
相关文章推荐
- 【最大流】【费用流】bzoj1834 [ZJOI2010]network 网络扩容
- bzoj1834 [ZJOI2010]network 网络扩容 最大流+费用流
- [bzoj1834][ZJOI2010] 网络扩容 最大流 费用流
- BZOJ1834 [ZJOI2010]network 网络扩容 【最大流,费用流】
- [BZOJ1834][ZJOI2010]network 网络扩容 最大流+费用流
- [BZOJ1834][ZJOI2010]网络扩容(最大流+费用流)
- bzoj 1834: [ZJOI2010]network 网络扩容【最大流+最小费用最大流】
- BZOJ 1834: [ZJOI2010]network 网络扩容(网络流+费用流)
- 【BZOJ】1834: [ZJOI2010]network 网络扩容(最大流+费用流)
- bzoj 1834: [ZJOI2010]network 网络扩容 网络流+费用流
- [BZOJ1834][ZJOI2010]网络扩容(费用流)
- BZOJ_1834_[ZJOI2010]network 网络扩容_费用流
- bzoj 1834 [ZJOI2010] network 网络扩容(费用流)
- Bzoj:[ZJOI2010]network 网络扩容:网络流,最大流+费用流
- [BZOJ1834][ZJOI2010]network 网络扩容(最大流+费用流)
- bzoj1834 [ZJOI2010]network 网络扩容(费用流)
- bzoj 1834: [ZJOI2010]network 网络扩容 -- 最大流+费用流
- BZOJ 1834 [ZJOI2010]network 网络扩容(费用流)
- BZOJ 1834: [ZJOI2010]network 网络扩容(最大流+最小费用最大流)
- [ZJOI2010][bzoj1834] 网络扩容 [费用流]