题意:给定一张有向图,每条边都有一个容量C和一个扩容费用W。这里扩容费用是指将容量扩大1所需的费用。
求: 1、 在不扩容的情况下,1到N的最大流;
2、 将1到N的最大流增加K所需的最小扩容费用。
30%的数据中,N<=100
100%的数据中,N<=1000,M<=5000,K<=10
思路:RYZ作业
第一问最大流即可
第二问网上很多题解都是在第一问的残余网络上构图,但是根本不需要
考虑边(x,y,z,w)
有容量为z,费用为0的免费流量,有容量为INF,费用为w的扩容付费流量,连这两种边
又因为求的是最大流为ans1+k时的最小费用,所以需要建立一个新的源点,从n连一条容量为ans1+k,费用为0的边来限制流量
费用流经典模型之一(模板?)
1 var head,vet,next,len1,len2,fan,x,y,z,w:array[1..200000]of longint; 2 pre:array[1..200000,1..2]of longint; 3 dis,gap,q:array[0..200000]of longint; 4 inq:array[1..200000]of boolean; 5 n,m,ans1,ans2,tot,i,src,source,s,k:longint; 6 7 procedure add(a,b,c,d:longint); 8 begin 9 inc(tot); 10 next[tot]:=head[a]; 11 vet[tot]:=b; 12 len1[tot]:=c; 13 len2[tot]:=d; 14 head[a]:=tot; 15 16 inc(tot); 17 next[tot]:=head[b]; 18 vet[tot]:=a; 19 len1[tot]:=0; 20 len2[tot]:=-d; 21 head[b]:=tot; 22 end; 23 24 function min(x,y:longint):longint; 25 begin 26 if x<y then exit(x); 27 exit(y); 28 end; 29 30 function dfs(u,aug:longint):longint; 31 var e,v,val,t,flow:longint; 32 begin 33 if u=src then exit(aug); 34 e:=head[u]; flow:=0; val:=s-1; 35 while e<>0 do 36 begin 37 v:=vet[e]; 38 if len1[e]>0 then 39 begin 40 if dis[u]=dis[v]+1 then 41 begin 42 t:=dfs(v,min(len1[e],aug-flow)); 43 len1[e]:=len1[e]-t; 44 len1[fan[e]]:=len1[fan[e]]+t; 45 flow:=flow+t; 46 if dis[source]>=s then exit(flow); 47 if aug=flow then break; 48 end; 49 val:=min(val,dis[v]); 50 end; 51 e:=next[e]; 52 end; 53 if flow=0 then 54 begin 55 dec(gap[dis[u]]); 56 if gap[dis[u]]=0 then dis[source]:=s; 57 dis[u]:=val+1; 58 inc(gap[dis[u]]); 59 end; 60 exit(flow); 61 end; 62 63 function maxflow:longint; 64 var ans:longint; 65 begin 66 fillchar(gap,sizeof(gap),0); 67 fillchar(dis,sizeof(dis),0); 68 gap[0]:=s; ans:=0; 69 while dis[source]<s do ans:=ans+dfs(source,maxlongint); 70 exit(ans); 71 end; 72 73 function spfa:boolean; 74 var t,u,e,v,i,w:longint; 75 begin 76 for i:=1 to s do 77 begin 78 dis[i]:=maxlongint>>1; 79 inq[i]:=false; 80 end; 81 t:=0; w:=1; q[1]:=source; inq[source]:=true; dis[source]:=0; 82 while t<w do 83 begin 84 inc(t); u:=q[t mod 3000]; 85 inq[u]:=false; 86 e:=head[u]; 87 while e<>0 do 88 begin 89 v:=vet[e]; 90 if (len1[e]>0)and(dis[u]+len2[e]<dis[v]) then 91 begin 92 pre[v,1]:=u; 93 pre[v,2]:=e; 94 dis[v]:=dis[u]+len2[e]; 95 if not inq[v] then 96 begin 97 inc(w); q[w mod 3000]:=v; inq[v]:=true; 98 end; 99 end; 100 e:=next[e]; 101 end; 102 end; 103 if dis[src]=maxlongint>>1 then exit(false); 104 exit(true); 105 end; 106 107 procedure mcf; 108 var k,e,t:longint; 109 begin 110 k:=src; t:=maxlongint; 111 while k<>source do 112 begin 113 t:=min(t,len1[pre[k,2]]); 114 k:=pre[k,1]; 115 end; 116 k:=src; 117 while k<>source do 118 begin 119 e:=pre[k,2]; 120 len1[e]:=len1[e]-t; 121 len1[fan[e]]:=len1[fan[e]]+t; 122 ans2:=ans2+t*len2[e]; 123 k:=pre[k,1]; 124 end; 125 end; 126 127 begin 128 assign(input,‘bzoj1834.in‘); reset(input); 129 assign(output,‘bzoj1834.out‘); rewrite(output); 130 readln(n,m,k); 131 for i:=1 to 200000 do 132 if i and 1=1 then fan[i]:=i+1 133 else fan[i]:=i-1; 134 for i:=1 to m do 135 begin 136 readln(x[i],y[i],z[i],w[i]); 137 add(x[i],y[i],z[i],w[i]); 138 end; 139 140 source:=1; src:=n; s:=n; 141 ans1:=maxflow; 142 fillchar(head,sizeof(head),0); 143 tot:=0; 144 for i:=1 to m do 145 begin 146 add(x[i],y[i],z[i],0); 147 add(x[i],y[i],maxlongint,w[i]); 148 end; 149 write(ans1,‘ ‘); 150 inc(src); inc(s); 151 add(n,src,ans1+k,0); 152 while spfa do mcf; 153 write(ans2); 154 close(input); 155 close(output); 156 end.
时间: 2024-10-14 01:54:40