题目描述
如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用。
输入
第一行包含四个正整数N、M、S、T,分别表示点的个数、有向边的个数、源点序号、汇点序号。
接下来M行每行包含四个正整数ui、vi、wi、fi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi),单位流量的费用为fi。
输出
一行,包含两个整数,依次为最大流量和在最大流量情况下的最小费用。
样例输入
4 5 4 3
4 2 30 2
4 3 20 3
2 3 20 1
2 1 30 9
1 3 40 5样例输出
50 280
555555本蒟蒻还不会zkw费用流,就先贴Edmond_Karp+SPFA和Primal_Dual的代码吧。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <vector> 5 #include <queue> 6 using namespace std; 7 8 struct edge { 9 int to,cap,cost,rev; 10 }; 11 12 typedef pair<int,int> P; 13 const int maxn=5000, maxm=50000, INF=0x7F7F7F7F; 14 int n,m; 15 vector <edge> G[maxn+1]; 16 17 edge make_edge(int to, int cap, int cost, int rev) { 18 edge x; 19 x.to=to, x.cap=cap, x.cost=cost, x.rev=rev; 20 return x; 21 } 22 23 void add_edge(int from, int to, int cap, int cost) { 24 G[from].push_back(make_edge(to,cap,cost,G[to].size())); 25 G[to].push_back(make_edge(from,0,-cost,G[from].size()-1)); 26 } 27 28 void init(int &s, int &t) { 29 scanf("%d%d%d%d",&n,&m,&s,&t); 30 for (int i=1; i<=m; i++) { 31 int u,v,w,f; 32 scanf("%d%d%d%d",&u,&v,&w,&f); 33 add_edge(u,v,w,f); 34 } 35 } 36 37 namespace EK_SPFA { 38 int dis[maxn+1]; 39 int prev[maxn+1]; 40 int pree[maxn+1]; 41 42 void bfs(int s) { 43 bool mark[maxn+1]; 44 memset(dis,0x7F,sizeof(dis)); 45 memset(prev,-1,sizeof(prev)); 46 memset(pree,-1,sizeof(pree)); 47 memset(mark,0,sizeof(mark)); 48 queue <int> q; 49 dis[s]=0; 50 q.push(s); 51 while (!q.empty()) { 52 int x=q.front(); 53 q.pop(); 54 mark[x]=false; 55 for (int i=0; i<G[x].size(); i++) { 56 edge &e=G[x][i]; 57 if (e.cap>0&&dis[x]+e.cost<dis[e.to]) { 58 dis[e.to]=dis[x]+e.cost; 59 prev[e.to]=x; 60 pree[e.to]=i; 61 if (!mark[e.to]) { 62 mark[e.to]=true; 63 q.push(e.to); 64 } 65 } 66 } 67 } 68 } 69 70 P min_cost_max_flow(int s, int t) { 71 int flow=0, cost=0; 72 for(;;) { 73 bfs(s); 74 if (dis[t]==INF) 75 return make_pair(flow,cost); 76 int d=INF; 77 for (int i=t; prev[i]!=-1; i=prev[i]) 78 d=min(d,G[prev[i]][pree[i]].cap); 79 flow+=d; 80 cost+=d*dis[t]; 81 for (int i=t; prev[i]!=-1; i=prev[i]) { 82 edge &e=G[prev[i]][pree[i]]; 83 e.cap-=d; 84 G[e.to][e.rev].cap+=d; 85 } 86 } 87 } 88 } 89 90 namespace Primal_Dual { 91 int dis[maxn+1]; 92 int h[maxn+1]; 93 int prev[maxn+1]; 94 int pree[maxn+1]; 95 96 void bfs(int s) { 97 priority_queue <P, vector<P>, greater<P> > q; 98 bool vis[maxn+1]; 99 memset(vis,0,sizeof(vis)); 100 memset(dis,0x7F,sizeof(dis)); 101 memset(prev,-1,sizeof(prev)); 102 memset(pree,-1,sizeof(pree)); 103 dis[s]=0; 104 q.push(make_pair(0,s)); 105 while (!q.empty()) { 106 int val=q.top().first, x=q.top().second; 107 q.pop(); 108 if (vis[x]) continue; 109 vis[x]=true; 110 for (int i=0; i<G[x].size(); i++) { 111 edge &e=G[x][i]; 112 if (e.cap>0&&dis[x]+e.cost+h[x]-h[e.to]<dis[e.to]&&!vis[e.to]) { 113 dis[e.to]=dis[x]+e.cost+h[x]-h[e.to]; 114 prev[e.to]=x; 115 pree[e.to]=i; 116 q.push(make_pair(dis[e.to],e.to)); 117 } 118 } 119 } 120 } 121 122 P min_cost_max_flow(int s, int t) { 123 int flow=0, cost=0; 124 memset(h,0,sizeof(h)); 125 for(;;) { 126 bfs(s); 127 if (dis[t]==INF) 128 return make_pair(flow,cost); 129 for (int i=1; i<=n; i++) 130 h[i]+=dis[i]; 131 int d=INF; 132 for (int i=t; prev[i]!=-1; i=prev[i]) 133 d=min(d,G[prev[i]][pree[i]].cap); 134 flow+=d; 135 cost+=d*h[t]; 136 for (int i=t; prev[i]!=-1; i=prev[i]) { 137 edge &e=G[prev[i]][pree[i]]; 138 e.cap-=d; 139 G[e.to][e.rev].cap+=d; 140 } 141 } 142 } 143 } 144 145 int main() { 146 int s,t; 147 init(s,t); 148 P ans=Primal_Dual::min_cost_max_flow(s,t); 149 printf("%d %d\n",ans.first,ans.second); 150 return 0; 151 }