「BZOJ1834」[ZJOI2010]网络扩容
最大流费用流二合一
注意跑费用流用的图要保留跑完最大流后的反向边
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1010,M=5010,oo=2e9; 4 int n,m,k,s,t; 5 int level[N],edge_tot,edge_tot2; 6 struct Edge{ 7 int from,to,flow,cap,w; 8 }edge[M<<1],edge2[M<<2]; 9 vector<int>point[N],point2[N]; 10 void add_edge(int f,int t,int c,int ww){ 11 edge[edge_tot]=(Edge){f,t,0,c,ww}; 12 point[f].push_back(edge_tot++); 13 return; 14 } 15 void add_edge2(int f,int t,int ff,int c,int ww){ 16 edge2[edge_tot2]=(Edge){f,t,ff,c,ww}; 17 point2[f].push_back(edge_tot2++); 18 return; 19 } 20 bool bfs(){ 21 memset(level,0,sizeof(level)); 22 queue<int>q; 23 q.push(s); 24 level[s]=1; 25 int x; 26 while(!q.empty()){ 27 x=q.front();q.pop(); 28 for(int i=0;i<point[x].size();i++){ 29 Edge& e=edge[point[x][i]]; 30 if(e.cap<=e.flow||level[e.to]) continue; 31 level[e.to]=level[e.from]+1; 32 q.push(e.to); 33 } 34 } 35 return level[t]; 36 } 37 int dfs(int k,int a){ 38 if(!a||k==t) return a; 39 int f,ans=0; 40 for(int i=0;i<point[k].size();i++){ 41 Edge& e=edge[point[k][i]]; 42 if(e.cap<=e.flow||level[e.to]!=level[k]+1) continue; 43 if(f=dfs(e.to,min(a,e.cap-e.flow))){ 44 a-=f,ans+=f; 45 edge[point[k][i]].flow+=f; 46 edge[point[k][i]^1].flow-=f; 47 if(!a) return ans; 48 } 49 } 50 return ans; 51 } 52 int dinic(){ 53 int ans=0; 54 while(bfs()) 55 ans+=dfs(s,oo); 56 return ans; 57 } 58 int dis[N],pre[N]; 59 bool inq[N]; 60 bool spfa(){ 61 queue<int>q; 62 memset(dis,127/2,sizeof(dis)); 63 q.push(s); 64 dis[s]=0,inq[s]=1; 65 int x; 66 while(!q.empty()){ 67 x=q.front();q.pop(); 68 inq[x]=0; 69 for(int i=0;i<point2[x].size();i++){ 70 Edge& e=edge2[point2[x][i]]; 71 if(e.cap<=e.flow) continue; 72 if(dis[e.to]>dis[x]+e.w){ 73 dis[e.to]=dis[x]+e.w,pre[e.to]=point2[x][i]; 74 if(!inq[e.to]){q.push(e.to);inq[e.to]=1;} 75 } 76 } 77 } 78 return dis[t]<=1e9; 79 } 80 int maxflowmincost(){ 81 int now,ans=0,f; 82 while(spfa()){ 83 now=t,f=oo; 84 while(now!=s){ 85 f=min(f,edge2[pre[now]].cap-edge2[pre[now]].flow); 86 now=edge2[pre[now]].from; 87 } 88 ans+=f*dis[t],now=t; 89 while(now!=s){ 90 edge2[pre[now]].flow+=f,edge2[pre[now]^1].flow-=f; 91 now=edge2[pre[now]].from; 92 } 93 } 94 return ans; 95 } 96 int main(){ 97 int t1,t2,t3,t4; 98 scanf("%d%d%d",&n,&m,&k); 99 for(int i=1;i<=m;i++){ 100 scanf("%d%d%d%d",&t1,&t2,&t3,&t4); 101 add_edge(t1,t2,t3,t4); 102 add_edge(t2,t1,0,-t4); 103 } 104 s=1,t=n; 105 printf("%d ",dinic()); 106 s=n+1; 107 add_edge2(s,1,0,k,0);add_edge2(1,s,0,0,0); 108 for(int i=0;i<m;i++){ 109 Edge& e=edge[i<<1]; 110 if(e.cap>e.flow){ 111 add_edge2(e.from,e.to,e.flow,e.cap,0); 112 } 113 add_edge2(e.from,e.to,0,k,e.w); 114 add_edge2(e.to,e.from,0,0,-e.w); 115 e=edge[i<<1|1]; 116 add_edge2(e.from,e.to,e.flow,0,0); 117 } 118 printf("%d",maxflowmincost()); 119 return 0; 120 }