網絡流的費用: 在實際應用中,與網絡流有關的問題,不僅涉及流量,而且還有費用的因素。網絡的每一條邊(v,w)除了給定容量cap(v,w)外,還定義了一個單位流量費用cost(v,w)。對於網絡中一個給定的流flow,其費用定義為:
最小費用最大流問題 給定網絡G,要求G的一個最大用流flow,使流的總費用最小。
求解MCMF問題的算法: 在這里各種算法的證明以及原理的詳解不再贅述,僅僅介紹算法的過程。相關內容感興趣的同學可以自己去搜索資料。 最小費用最大流最常用和基本的算法我們可以稱它為最小費用路算法,其思想與求最大流的增廣路算法類似,不斷在殘流網絡中尋找從源s到匯t的最小費用路,即殘流網絡中從s到t的以費用為權的最短路,然后沿最小費用路增流,直至找到最小費用流。 殘流網絡中邊的費用定義為:
當殘流網絡中邊(v,w)是向前邊時,其費用為cost(v,w); 當(v,w)是向后邊時,其費用為-cost(w,v)。
最小費用流的最小費用路算法
步驟0:初始可行0流。 步驟1:如果不存在最小費用路,則計算結束,已經找到最小費用流;否則用最短路算法在殘流網絡中找從s到t的最小費用可增廣路,轉步驟2。 步驟2:沿找到的最小費用可增廣路增流,並轉步驟1。
最小費用路算法的復雜度主要依靠於求最短路的方法,由於負權的存在,不會選擇dijstra等算法,一般bellman-ford,spfa等用來解決費用流的最短路問題。
模版題:
POJ 2135
代碼:

1 #include <iostream>
2 #include <cstring>
3 #include <cstdio>
4 #include <queue>
5 using namespace std;
6 int sumFlow;
7 const int MAXN = 1010;
8 const int MAXM = 1000200;
9 const int INF = 1000000000;
10 struct Edge
11 {
12 int u;
13 int v;
14 int cap;
15 int cost;
16 int next;
17 }edge[MAXM<< 2];
18 int NE;
19 int head[MAXN], dist[MAXN], pp[MAXN];
20 bool vis[MAXN];
21 void init()
22 {
23 NE= 0;
24 memset(head,- 1, sizeof(head));
25 }
26 void addedge( int u, int v, int cap, int cost)
27 {
28 edge[NE].u=u;edge[NE].v=v;edge[NE].cap=cap;edge[NE].cost=cost;
29 edge[NE].next=head[u];head[u]=NE++;
30 edge[NE].u=v;edge[NE].v=u;edge[NE].cap= 0;edge[NE].cost=-cost;
31 edge[NE].next=head[v];head[v]=NE++;
32 }
33 bool SPFA( int s, int t, int n)
34 {
35 int i,u,v;
36 queue< int>qu;
37 memset(vis, false, sizeof(vis));
38 memset(pp,- 1, sizeof(pp));
39 for(i= 0;i<=n;i++)
40 dist[i]=INF;
41 vis[s]= true;
42 dist[s]= 0;
43 qu.push(s);
44 while(!qu.empty())
45 {
46 u=qu.front();
47 qu.pop();
48 vis[u]= false;
49 for(i=head[u];i!=- 1;i=edge[i].next)
50 {
51 v=edge[i].v;
52 if(edge[i].cap&&dist[v]>dist[u]+edge[i].cost)
53 {
54 dist[v]=dist[u]+edge[i].cost;
55 pp[v]=i;
56 if(!vis[v])
57 {
58 qu.push(v);
59 vis[v]= true;
60 }
61 }
62 }
63 }
64 if(dist[t]==INF)
65 return false;
66 return true;
67 }
68 int MCMF( int s, int t, int n)
69 {
70 int flow= 0; // 總流量
71 int i,minflow,mincost;
72 mincost= 0;
73 while(SPFA(s,t,n))
74 {
75 minflow=INF+ 1;
76 for(i=pp[t];i!=- 1;i=pp[edge[i].u])
77 if(edge[i].cap<minflow)
78 minflow=edge[i].cap;
79 flow+=minflow;
80 for(i=pp[t];i!=- 1;i=pp[edge[i].u])
81 {
82 edge[i].cap-=minflow;
83 edge[i^ 1].cap+=minflow;
84 }
85 mincost+=dist[t]*minflow;
86 }
87 sumFlow=flow; // 最大流
88 return mincost;
89 }
90 int main()
91 {
92 int n,m;
93 int u,v,c;
94 while(~scanf( " %d%d ",&n,&m))
95 {
96 init();
97 int S= 0;
98 int T=n+ 1;
99 while(m--)
100 {
101 scanf( " %d%d%d ",&u,&v,&c);
102 addedge(u,v, 1,c);
103 addedge(v,u, 1,c);
104 }
105 addedge(S, 1, 2, 0);
106 addedge(n,T, 2, 0);
107 int ans=MCMF(S,T,T+ 1);
108 printf( " %d\n ",ans);
109 }
110 return 0;
111 }
112
2 #include <cstring>
3 #include <cstdio>
4 #include <queue>
5 using namespace std;
6 int sumFlow;
7 const int MAXN = 1010;
8 const int MAXM = 1000200;
9 const int INF = 1000000000;
10 struct Edge
11 {
12 int u;
13 int v;
14 int cap;
15 int cost;
16 int next;
17 }edge[MAXM<< 2];
18 int NE;
19 int head[MAXN], dist[MAXN], pp[MAXN];
20 bool vis[MAXN];
21 void init()
22 {
23 NE= 0;
24 memset(head,- 1, sizeof(head));
25 }
26 void addedge( int u, int v, int cap, int cost)
27 {
28 edge[NE].u=u;edge[NE].v=v;edge[NE].cap=cap;edge[NE].cost=cost;
29 edge[NE].next=head[u];head[u]=NE++;
30 edge[NE].u=v;edge[NE].v=u;edge[NE].cap= 0;edge[NE].cost=-cost;
31 edge[NE].next=head[v];head[v]=NE++;
32 }
33 bool SPFA( int s, int t, int n)
34 {
35 int i,u,v;
36 queue< int>qu;
37 memset(vis, false, sizeof(vis));
38 memset(pp,- 1, sizeof(pp));
39 for(i= 0;i<=n;i++)
40 dist[i]=INF;
41 vis[s]= true;
42 dist[s]= 0;
43 qu.push(s);
44 while(!qu.empty())
45 {
46 u=qu.front();
47 qu.pop();
48 vis[u]= false;
49 for(i=head[u];i!=- 1;i=edge[i].next)
50 {
51 v=edge[i].v;
52 if(edge[i].cap&&dist[v]>dist[u]+edge[i].cost)
53 {
54 dist[v]=dist[u]+edge[i].cost;
55 pp[v]=i;
56 if(!vis[v])
57 {
58 qu.push(v);
59 vis[v]= true;
60 }
61 }
62 }
63 }
64 if(dist[t]==INF)
65 return false;
66 return true;
67 }
68 int MCMF( int s, int t, int n)
69 {
70 int flow= 0; // 總流量
71 int i,minflow,mincost;
72 mincost= 0;
73 while(SPFA(s,t,n))
74 {
75 minflow=INF+ 1;
76 for(i=pp[t];i!=- 1;i=pp[edge[i].u])
77 if(edge[i].cap<minflow)
78 minflow=edge[i].cap;
79 flow+=minflow;
80 for(i=pp[t];i!=- 1;i=pp[edge[i].u])
81 {
82 edge[i].cap-=minflow;
83 edge[i^ 1].cap+=minflow;
84 }
85 mincost+=dist[t]*minflow;
86 }
87 sumFlow=flow; // 最大流
88 return mincost;
89 }
90 int main()
91 {
92 int n,m;
93 int u,v,c;
94 while(~scanf( " %d%d ",&n,&m))
95 {
96 init();
97 int S= 0;
98 int T=n+ 1;
99 while(m--)
100 {
101 scanf( " %d%d%d ",&u,&v,&c);
102 addedge(u,v, 1,c);
103 addedge(v,u, 1,c);
104 }
105 addedge(S, 1, 2, 0);
106 addedge(n,T, 2, 0);
107 int ans=MCMF(S,T,T+ 1);
108 printf( " %d\n ",ans);
109 }
110 return 0;
111 }
112