BZOJ1834: [ZJOI2010]network 网络扩容
2016-12-21 18:17
211 查看
题目链接
第一问直接最大流。第二问,在残量网络中重新建图:
对于剩余流量不足K的边(x,y),建新边,流量为K-W[i],费用为C[i]。对于剩余流量不为0的边,建新边,流量为W[i],费用为0。
然后费用流就可以了。
为什么这样建呢?
自己YY的是:每条边再流过的流量最多为K,则对于每条边,可流的流量不需要费用,不足的流量就补齐,有费用。
然而理想很美好,现实很骨感。开开心心的交了,WA!!??
很不服气。。找数据测,90!!?第一组就错了。
然后看看dalao们的题解,又想了半天,才知道自己错在哪里。
正确的做法是:
从第一问的残留网络上继续建图,对残留网络上的每一条边建一条容量是∞费用是w的边(反向弧容量为0,费用为-w),然后建一个超级源点,从超级源向1建一条容量为k,费用为0的边,对这个图进行最小费用最大流算法。
那么之前的做法错在哪里呢?
因为最大流的流法可以有多种方案,而计算的时候,只算了总流量,但只是一种方案。而原先的做法是默认了第二问中仍用第一问中求出来的方案来完成,显然错误。(吐槽:数据是真的水。。)
正解(100)
【分析】
刚看到这道题。想了想。哇,我好像会做~第一问直接最大流。第二问,在残量网络中重新建图:
对于剩余流量不足K的边(x,y),建新边,流量为K-W[i],费用为C[i]。对于剩余流量不为0的边,建新边,流量为W[i],费用为0。
然后费用流就可以了。
为什么这样建呢?
自己YY的是:每条边再流过的流量最多为K,则对于每条边,可流的流量不需要费用,不足的流量就补齐,有费用。
然而理想很美好,现实很骨感。开开心心的交了,WA!!??
很不服气。。找数据测,90!!?第一组就错了。
然后看看dalao们的题解,又想了半天,才知道自己错在哪里。
正确的做法是:
从第一问的残留网络上继续建图,对残留网络上的每一条边建一条容量是∞费用是w的边(反向弧容量为0,费用为-w),然后建一个超级源点,从超级源向1建一条容量为k,费用为0的边,对这个图进行最小费用最大流算法。
那么之前的做法错在哪里呢?
因为最大流的流法可以有多种方案,而计算的时候,只算了总流量,但只是一种方案。而原先的做法是默认了第二问中仍用第一问中求出来的方案来完成,显然错误。(吐槽:数据是真的水。。)
【代码】
第一种思路的代码(90)#include <cstdio> #include <iostream> #include <queue> #include <vector> #include <algorithm> #include <cstring> #include <cmath> #include <stack> #define N 1005 #define M 20005 #define INF 1000000000 using namespace std; typedef long long ll; typedef pair<ll,ll> pa; int read() { int x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();} while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,m,K,cnt=1,S,T,ans,Cnt=1; int b[M],p ,nextedge[M],w[M],c[M]; int B[10005],P ,Next[10005],W[10005],C[5010],cur ; int Dis ,Pre ,Level ; bool Flag ; void Add(int x,int y,int z,int cost) { cnt++; b[cnt]=y; nextedge[cnt]=p[x]; p[x]=cnt; w[cnt]=z; c[cnt]=cost; } void Anode(int x,int y,int z,int cost){ Add(x,y,z,cost);Add(y,x,0,-cost); } void Ins(int x,int y,int z) { Cnt++; B[Cnt]=y; Next[Cnt]=P[x]; P[x]=Cnt; W[Cnt]=z; } void Insert(int x,int y,int z){ Ins(x,y,z);Ins(y,x,0); } bool Bfs() { queue<int>q; for(int i=1;i<=n;i++) Level[i]=0; Level[1]=1; q.push(1); while(!q.empty()) { int k=q.front();q.pop(); for(int i=P[k];i;i=Next[i]) { int v=B[i]; if(!Level[v]&&W[i]) { Level[v]=Level[k]+1; q.push(v); } } } return Level ; } int Dfs(int x,int maxf) { if(x==n||!maxf) return maxf; int rtn=0; for(int i=cur[x];i&&maxf>rtn;i=Next[i]) { int v=B[i],f=W[i]; if(Level[v]==Level[x]+1&&f) { f=Dfs(v,min(maxf-rtn,f)); W[i]-=f;W[i^1]+=f; if(W[i]>0) cur[x]=i; rtn+=f; } } return rtn; } void Dinic() { int rtn=0; while(Bfs()) { for(int i=1;i<=n;i++) cur[i]=P[i]; rtn+=Dfs(1,INF); } printf("%d ",rtn); } void Input_Init() { n=read(),m=read(),K=read(); for(int i=1;i<=m;i++) { static int x,y,z; x=read(),y=read(),z=read(),C[i]=read(); Insert(x,y,z); } } bool bfs() { queue<int>q; q.push(S); for(int i=0;i<=T;i++) Dis[i]=INF; Dis[0]=0; while(!q.empty()) { int k=q.front();q.pop(); Flag[k]=0; for(int i=p[k];i;i=nextedge[i]) { int v=b[i],f=w[i]; if(Dis[v]>Dis[k]+c[i]&&f) { Dis[v]=Dis[k]+c[i]; Pre[v]=i; if(!Flag[v]) { Flag[v]=1; q.push(v); } } } } return Dis[T]!=INF; } void Mcf() { int maxf=INF; for(int i=Pre[T];i;i=Pre[b[i^1]]) maxf=min(maxf,w[i]); for(int i=Pre[T];i;i=Pre[b[i^1]]) { w[i]-=maxf; w[i^1]+=maxf; ans+=maxf*c[i]; } } void MCF() { while(bfs()) Mcf(); printf("%d\n",ans); } void Build_Graph() { Anode(0,1,K,0);T=n; for(int i=2;i<=Cnt;i+=2) { static int x,y; x=B[i^1],y=B[i]; if(W[i]<K) Anode(x,y,K-W[i],C[i>>1]); if(W[i]) Anode(x,y,W[i],0); } } int main() { Input_Init(); Dinic(); Build_Graph(); MCF(); return 0; }
正解(100)
#include <cstdio> #include <iostream> #include <queue> #include <vector> #include <algorithm> #include <cstring> #include <cmath> #include <stack> #define N 1005 #define M 20005 #define INF 1000000000 using namespace std; typedef long long ll; typedef pair<ll,ll> pa; int read() { int x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();} while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,m,K,cnt=1,S,T,ans,Cnt=1; int b[M],p ,nextedge[M],w[M],c[M],cur ; int Dis ,Pre ,Level ; bool Flag ; void Add(int x,int y,int z,int cost) { cnt++; b[cnt]=y; nextedge[cnt]=p[x]; p[x]=cnt; w[cnt]=z; c[cnt]=cost; } void Anode(int x,int y,int z,int cost){ Add(x,y,z,cost);Add(y,x,0,-cost); } bool Bfs() { queue<int>q; for(int i=1;i<=n;i++) Level[i]=0; Level[1]=1; q.push(1); while(!q.empty()) { int k=q.front();q.pop(); for(int i=p[k];i;i=nextedge[i]) { int v=b[i]; if(!Level[v]&&w[i]) { Level[v]=Level[k]+1; q.push(v); } } } return Level ; } int Dfs(int x,int maxf) { if(x==n||!maxf) return maxf; int rtn=0; for(int i=cur[x];i&&maxf>rtn;i=nextedge[i]) { int v=b[i],f=w[i]; if(Level[v]==Level[x]+1&&f) { f=Dfs(v,min(maxf-rtn,f)); w[i]-=f;w[i^1]+=f; if(w[i]>0) cur[x]=i; rtn+=f; } } return rtn; } void Dinic() { int rtn=0; while(Bfs()) { for(int i=1;i<=n;i++) cur[i]=p[i]; rtn+=Dfs(1,INF); } printf("%d ",rtn); } void Input_Init() { n=read(),m=read(),K=read(); for(int i=1;i<=m;i++) { static int x,y,z,cost; x=read(),y=read(),z=read(),cost=read(); Anode(x,y,z,cost); } } bool bfs() { queue<int>q; q.push(S); for(int i=0;i<=T;i++) Dis[i]=INF; Dis[0]=0; while(!q.empty()) { int k=q.front();q.pop(); Flag[k]=0; for(int i=p[k];i;i=nextedge[i]) { int v=b[i],f=w[i]; if(Dis[v]>Dis[k]+c[i]&&f) { Dis[v]=Dis[k]+c[i]; Pre[v]=i; if(!Flag[v]) { Flag[v]=1; q.push(v); } } } } return Dis[T]!=INF; } void Mcf() { int maxf=INF; for(int i=Pre[T];i;i=Pre[b[i^1]]) maxf=min(maxf,w[i]); for(int i=Pre[T];i;i=Pre[b[i^1]]) { w[i]-=maxf; w[i^1]+=maxf; ans+=maxf*c[i]; } } void MCF() { while(bfs()) Mcf(); printf("%d\n",ans); } void Build_Graph() { T=n; Cnt=cnt; for(int i=2;i<=Cnt;i+=2) { static int x,y; x=b[i^1],y=b[i]; Anode(x,y,INF,c[i]); c[i]=c[i+1]=0; } Anode(0,1,K,0); } int main() { Input_Init(); Dinic(); Build_Graph(); MCF(); return 0; }
相关文章推荐
- BZOJ1834 [ZJOI2010] network 网络扩容
- BZOJ 1834 [ZJOI2010]network 网络扩容
- bzoj1834 [ZJOI2010]network 网络扩容
- 【最大流/费用流】BZOJ1834-[ZJOI2010]network 网络扩容
- bzoj 1834 [ZJOI2010]network 网络扩容(MCMF)
- 【最大流】【费用流】bzoj1834 [ZJOI2010]network 网络扩容
- 【bzoj1834】[ZJOI2010]network 网络扩容 费用流
- bzoj 1834 [ZJOI2010] network 网络扩容 题解
- 【bzoj1834】[ZJOI2010]network 网络扩容(wikioi1362)
- 【BZOJ】1834: [ZJOI2010]network 网络扩容(最大流+费用流)
- BZOJ 1834: [ZJOI2010]network 网络扩容(最大流+最小费用最大流)
- [BZOJ 1834] [ZJOI2010]network 网络扩容
- 【BZOJ 1834】 [ZJOI2010]network 网络扩容
- bzoj 1834: [ZJOI2010]network 网络扩容(isap+费用流)
- 【bzoj1834】[ZJOI2010]network 网络扩容
- [BZOJ1834][ZJOI2010]network 网络扩容(最大流+费用流)
- 【BZOJ 1834】 [ZJOI2010]network 网络扩容
- bzoj1834 [ZJOI2010]network 网络扩容
- bzoj1834[ZJOI2010]network 网络扩容【最大流+费用流】
- bzoj 1834: [ZJOI2010]network 网络扩容