【BZOJ】【1834】【ZJOI2010】Network 网络扩容
网络流/费用流
这题……我一开始sb了。
第一问简单的最大流……
第二问是要建费用流的图的……但是是在第一问的最大流跑完以后的残量网络上建,而不是重建……
我们令残量网络上原有的弧的费用全部为0(因为如果还能走就不需要扩容),而新加的弧容量为INF,费用为给定的w[i]。
然后跑费用流就好了……这样建的话如果是不用扩容的边它就会自己走费用为0的弧。
RE/TLE:费用流扩展时的队列/边集数组的大小 M 开小了,队列长度从N改成M,M大小从20000改成50000后AC
1 /************************************************************** 2 Problem: 1834 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:36 ms 7 Memory:3824 kb 8 ****************************************************************/ 9 10 //BZOJ 1834 11 #include<vector> 12 #include<cstdio> 13 #include<cstring> 14 #include<cstdlib> 15 #include<iostream> 16 #include<algorithm> 17 #define rep(i,n) for(int i=0;i<n;++i) 18 #define F(i,j,n) for(int i=j;i<=n;++i) 19 #define D(i,j,n) for(int i=j;i>=n;--i) 20 #define pb push_back 21 using namespace std; 22 inline int getint(){ 23 int v=0,sign=1; char ch=getchar(); 24 while(ch<‘0‘||ch>‘9‘){ if (ch==‘-‘) sign=-1; ch=getchar();} 25 while(ch>=‘0‘&&ch<=‘9‘){ v=v*10+ch-‘0‘; ch=getchar();} 26 return v*sign; 27 } 28 const int N=1002,M=50000,INF=~0u>>2; 29 typedef long long LL; 30 /******************tamplate*********************/ 31 int n,m,k,ans; 32 struct edge{int from,to,v,c,w;}; 33 struct Net{ 34 edge E[M],G[M]; 35 int head[N],next[M],cnt; 36 void ins(int x,int y,int v,int c){ 37 E[++cnt]=(edge){x,y,v,0,c}; 38 next[cnt]=head[x]; head[x]=cnt; 39 } 40 void add(int x,int y,int v,int c){ 41 ins(x,y,v,c); ins(y,x,0,-c); 42 } 43 void Ins(int x,int y,int v,int c){ 44 E[++cnt]=(edge){x,y,v,c,0}; 45 next[cnt]=head[x]; head[x]=cnt; 46 } 47 void Add(int x,int y,int v,int c){ 48 Ins(x,y,v,c); Ins(y,x,0,-c); 49 } 50 int s,t,d[N],Q[M]; 51 bool mklevel(){ 52 F(i,1,n) d[i]=-1; 53 d[s]=0; 54 int l=0,r=-1; 55 Q[++r]=s; 56 while(l<=r){ 57 int x=Q[l++]; 58 for(int i=head[x];i;i=next[i]) 59 if (d[E[i].to]==-1 && E[i].v){ 60 d[E[i].to]=d[x]+1; 61 Q[++r]=E[i].to; 62 } 63 } 64 return d[t]!=-1; 65 } 66 int dfs(int x,int a){ 67 if (x==t) return a; 68 int flow=0; 69 for(int i=head[x];i && flow<a;i=next[i]) 70 if (E[i].v && d[E[i].to]==d[x]+1){ 71 int f=dfs(E[i].to,min(a-flow,E[i].v)); 72 E[i].v-=f; 73 E[i^1].v+=f; 74 flow+=f; 75 } 76 if (!flow) d[x]=-1; 77 return flow; 78 } 79 void Dinic(){ 80 while(mklevel()) ans+=dfs(s,INF); 81 } 82 int from[M]; 83 bool inq[N]; 84 bool spfa(){ 85 int l=0,r=-1; 86 F(i,0,n) d[i]=INF; 87 d[s]=0; Q[++r]=s; inq[s]=1; 88 while(l<=r){ 89 int x=Q[l++]; 90 inq[x]=0; 91 for(int i=head[x];i;i=next[i]) 92 if (E[i].v>0 && d[x]+E[i].c<d[E[i].to]){ 93 d[E[i].to]=d[x]+E[i].c; 94 from[E[i].to]=i; 95 if (!inq[E[i].to]){ 96 Q[++r]=E[i].to; 97 inq[E[i].to]=1; 98 } 99 } 100 } 101 return d[n]!=INF; 102 } 103 void mcf(){ 104 int x=INF; 105 for(int i=from[t];i;i=from[E[i].from]) 106 x=min(x,E[i].v); 107 for(int i=from[t];i;i=from[E[i].from]){ 108 E[i].v-=x; 109 E[i^1].v+=x; 110 ans+=x*E[i].c; 111 } 112 } 113 void build(){ 114 int t=cnt; 115 for(int i=2;i<=t;i+=2) 116 Add(E[i].from,E[i].to,INF,E[i].w); 117 } 118 void init(){ 119 n=getint(); m=getint(); k=getint(); 120 int x,y,z,w; 121 cnt=1; 122 s=1; t=n; 123 F(i,1,m){ 124 x=getint(); y=getint(); z=getint(); w=getint(); 125 add(x,y,z,w); 126 } 127 Dinic(); build(); 128 printf("%d ",ans); 129 ans=0; s=0; 130 ins(s,1,k,0); 131 while(spfa()) mcf(); 132 printf("%d\n",ans); 133 } 134 }G1; 135 136 int main(){ 137 #ifndef ONLINE_JUDGE 138 freopen("1834.in","r",stdin); 139 freopen("1834.out","w",stdout); 140 #endif 141 G1.init(); 142 return 0; 143 }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。