SCL--最小费用最大流

2015-09-04 22:42:49

总结:由于以前的代码风格不同,所以现在有必要总(zhan)结(tie)一个最新的MCMF模板了。

用SPFA实现的,必要时可以上优化过的Dijstra。

 

 1 struct edge{
 2     int v,next,cost,cp;
 3 };
 4 
 5 struct MCMF{
 6     edge e[MAXM];
 7     int sou,sin;
 8     int first[MAXN],ecnt;
 9     int dis[MAXN];
10     int prev[MAXN],pree[MAXN],inq[MAXN];
11     void init(int a,int b){
12         sou = a;
13         sin = b;
14         memset(first,-1,sizeof(first));
15         ecnt = 0;
16     }
17     void add_edge(int u,int v,int cap,int fee){
18         e[ecnt].next = first[u];
19         e[ecnt].v = v;
20         e[ecnt].cp = cap;
21         e[ecnt].cost = fee;
22         first[u] = ecnt++;
23 
24         e[ecnt].next = first[v];
25         e[ecnt].v = u;
26         e[ecnt].cp = 0;
27         e[ecnt].cost = -fee;
28         first[v] = ecnt++;
29     }
30     bool Spfa(){
31         fill(dis,dis + MAXN,INF);
32         dis[sou] = 0;
33         MEM(prev,-1),MEM(inq,0);
34         queue<int> Q;
35         Q.push(sou);
36         while(!Q.empty()){
37             int x = Q.front(); Q.pop();
38             inq[x] = 0;
39             for(int i = first[x]; ~i; i = e[i].next){
40                 if(e[i].cp <= 0) continue;
41                 int v = e[i].v;
42                 if(dis[x] + e[i].cost < dis[v]){
43                     dis[v] = dis[x] + e[i].cost;
44                     prev[v] = x;
45                     pree[v] = i;
46                     if(inq[v] == 0){
47                         inq[v] = 1;
48                         Q.push(v);
49                     }
50                 }
51             }
52         }
53         return prev[sin] != -1;
54     }
55     int Solve(){
56         //int sumf = 0;
57         int min_cost = 0;
58         while(Spfa()){
59             int minf = INF;
60             for(int i = sin; i != sou; i = prev[i]){
61                 int id = pree[i];
62                 minf = min(minf,e[id].cp);
63             }
64             for(int i = sin; i != sou; i = prev[i]){
65                 int id = pree[i];
66                 e[id].cp -= minf;
67                 e[id ^ 1].cp += minf;
68             }
69             //sumf += minf;
70             min_cost += dis[sin] * minf;
71         }
72         //printf("flow : %d\n",sumf);
73         return min_cost;
74     }
75 }MC;

 

posted @ 2015-09-04 22:45  Naturain  阅读(174)  评论(0编辑  收藏  举报