MCMF(最小费用最大流)

在一个网络中每段路径都有“容量”和“费用”两个限制的条件下,此类问题的研究试图寻找出:流量从A到B,如何选择路径、分配经过路径的流量,可以达到所用的费用最小的要求。如n辆卡车要运送物品,从A地到B地。由于每条路段都有不同的路费要缴纳,每条路能容纳的车的数量有限制,最小费用最大流问题指如何分配卡车的出发路径可以达到费用最低,物品又能全部送到。

 1 //最小费用最大流模版.求最大费用最大流建图时把费用取负即可。
 2 //无向边转换成有向边时需要拆分成两条有向边。即两次加边。
 3 const int maxn = 1010;
 4 const int maxm = 1000200;
 5 const int inf = 1000000000;
 6 struct Edge
 7 {
 8     int v, cap, cost, next;
 9 }p[maxm << 1];
10 int e, sumFlow, n, m, st, en;
11 int head[maxn], dis[maxn], pre[maxn];
12 bool vis[maxn];
13 void init()
14 {
15     e=0;
16     memset(head,-1,sizeof(head));
17 }
18 void addEdge(int u,int v,int cap,int cost)
19 {
20     p[e].v = v; p[e].cap = cap; p[e].cost = cost;
21     p[e].next = head[u]; head[u] = e++;
22     p[e].v = u; p[e].cap = 0; p[e].cost = - cost;
23     p[e].next = head[v]; head[v] = e++;
24 }
25 bool spfa(int s,int t, int n)
26 {
27     int u,v;
28     queue<int>q;
29     memset(vis,false,sizeof(vis));
30     memset(pre,-1,sizeof(pre));
31     for(int i = 0; i <= n; ++i) 
32         dis[i] = inf;
33     vis[s] = true;
34     dis[s] = 0;
35     q.push(s);
36     while(!q.empty())
37     {
38         u = q.front();
39         q.pop();
40         vis[u] = false;
41         for(int i = head[u]; i != -1; i = p[i].next)
42         {
43             v = p[i].v;
44             if(p[i].cap && dis[v] > dis[u] + p[i].cost)
45             {
46                 dis[v] = dis[u] + p[i].cost;
47                 pre[v] = i;
48                 if(!vis[v])
49                 {
50                     q.push(v);
51                     vis[v]=true;
52                 }
53             }
54         }
55      }
56      if(dis[t] == inf) 
57          return false;
58      return true;
59 }
60 int MCMF(int s,int t,int n)
61 {
62     int flow = 0; // 总流量
63     int minflow, mincost;
64     mincost=0;
65     while(spfa(s,t,n))
66     {
67         minflow = inf + 1;
68         for(int i = pre[t]; i != -1; i = pre[p[i^1].v])
69             if(p[i].cap < minflow)
70                 minflow = p[i].cap;
71         flow += minflow;
72         for(int i=pre[t];i!=-1;i=pre[p[i^1].v])
73         {
74             p[i].cap -= minflow;
75             p[i^1].cap += minflow;
76         }
77         mincost += dis[t] * minflow;
78     }
79     sumFlow = flow; // 最大流
80     return mincost;
81 }

 

posted @ 2013-04-19 13:35  Missa  阅读(3081)  评论(0编辑  收藏  举报