最小费用流
zkw费用流+当前弧优化
1 var 2 o,v:array[0..1600] of boolean; 3 f,s,d,dis:array[0..1600] of longint; 4 next,p,c,w:array[-100000..100000] of longint; 5 i,j,k,l,y,t,ss,tt,n,ans,imp,flow:longint; 6 procedure link(i,j,k,l:longint); 7 begin 8 inc(t); 9 next[t]:=d[i]; d[i]:=t; p[t]:=j; c[t]:=k; w[t]:=l; 10 next[-t]:=d[j]; d[j]:=-t; p[-t]:=i; w[-t]:=-l; 11 end; 12 function dfs(i,flow:longint):longint; 13 var j,k,l,min:longint; 14 begin 15 if i=tt then 16 begin 17 inc(ans,dis[i]*flow); exit(flow); 18 end; 19 k:=s[i]; j:=p[k]; dfs:=0; 20 o[i]:=true; v[i]:=true; 21 while k<>0 do 22 begin 23 l:=dis[i]+w[k]-dis[j]; min:=flow; 24 if c[k]<min then min:=c[k]; 25 if(min>0)and(l<f[j])then f[j]:=l; 26 if(min>0)and(l=0)and(not o[j])then 27 begin 28 l:=dfs(j,min); 29 inc(dfs,l); dec(flow,l); 30 dec(c[k],l); inc(c[-k],l); 31 end; 32 if flow=0 then break; 33 s[i]:=next[s[i]]; 34 k:=s[i]; j:=p[k]; 35 end; 36 o[i]:=false; 37 end; 38 begin 39 build; 40 repeat 41 for i:=ss to tt do s[i]:=d[i]; 42 fillchar(v,sizeof(v),false); 43 fillchar(f,sizeof(f),1); 44 inc(flow,dfs(ss,1 shl 20)); 45 imp:=1 shl 20; 46 for i:=ss to tt do 47 if(not v[i])and(f[i]<imp)then imp:=f[i]; 48 for i:=ss to tt do if not v[i] then inc(dis[i],imp); 49 until imp=1 shl 20; 50 writeln(ans); 51 end.
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int INF=1000000000; 4 int o[1600],v[1600],f[1600],c[1600],s[1600],dis[1600]; 5 int b[200001],p[200001],d[200001],w[200001]; 6 int j,k,ss,tt,n,ans,imp,flow,cnt; 7 void link(int i,int j,int k,int l) 8 { 9 cnt++; b[cnt]=c[i]; c[i]=cnt; p[cnt]=j; d[cnt]=k; w[cnt]=l; 10 cnt++; b[cnt]=c[j]; c[j]=cnt; p[cnt]=i; d[cnt]=0; w[cnt]=-l; 11 } 12 int dfs(int x,int flow) 13 { 14 if(x==tt){ ans+=dis[x]*flow; return flow; } 15 int ans2=0; o[x]=1; v[x]=1; 16 for(int i=s[x];i;i=b[i]) 17 { 18 int j=p[i]; int l=dis[x]+w[i]-dis[j]; int mi=min(flow,d[i]); 19 if((mi>0)and(l<f[j]))f[j]=l; 20 if((mi>0)and(l==0)and(!o[j])) 21 { 22 l=dfs(j,mi); 23 ans2+=l; flow-=l; d[i]-=l; d[i^1]+=l; 24 } 25 if(flow==0)break; s[x]=b[s[x]]; 26 } 27 o[x]=0; return ans2; 28 } 29 int main() 30 { 31 cnt=1; build; 32 while(1) 33 { 34 for(int i=ss;i<=tt;i++)s[i]=c[i]; 35 memset(v,0,sizeof(v)); for(int i=ss;i<=tt;i++)f[i]=INF; 36 flow+=dfs(ss,INF); imp=INF; 37 for(int i=ss;i<=tt;i++)if((!v[i])and(f[i]<imp))imp=f[i]; 38 if(imp==INF)break; 39 for(int i=ss;i<=tt;i++)if(!v[i])dis[i]+=imp; 40 } 41 printf("%d %d\n",flow,ans); 42 }