Poj--2135(最小费用最大流)

2014-12-21 23:00:54

思路:最小费用最大流启蒙题。

  巫大叔的书里写了最小费用,把它和最大流分了开来。。。然后看了别人博客,就是在求增广路的时候求最短增广路,套上spfa。

  这题其实就是从1到n求两边最短增广路就行了,几个注意点:

  (1)无向边!所以要双向建边(由于还要间负费用反向边,所以其实是对于一条无向边要建4条有向边)

  (2)最短增广路只用求两次(因为来回)

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <vector>
 6 #include <map>
 7 #include <set>
 8 #include <stack>
 9 #include <queue>
10 #include <iostream>
11 #include <algorithm>
12 using namespace std;
13 #define lp (p << 1)
14 #define rp (p << 1|1)
15 #define getmid(l,r) (l + (r - l) / 2)
16 #define MP(a,b) make_pair(a,b)
17 typedef long long ll;
18 typedef unsigned long long ull;
19 const int INF = 1 << 30;
20 const int maxn = 1010;
21 const int Maxn = 10010;
22 
23 int first[maxn],next[Maxn << 2],ver[Maxn << 2],cost[Maxn << 2],cp[Maxn << 2],ecnt;
24 int N,M,pre[maxn],edge[maxn],inq[maxn],dis[maxn];
25 queue<int> Q;
26 
27 void Init(){
28     memset(first,-1,sizeof(first));
29     ecnt = 0;
30 }
31 
32 void Add_edge(int u,int v,int fee){
33     next[++ecnt] = first[u];
34     ver[ecnt] = v;
35     cost[ecnt] = fee;
36     cp[ecnt] = 1;
37     first[u] = ecnt;
38 
39     next[++ecnt] = first[v];
40     ver[ecnt] = u;
41     cost[ecnt] = -fee;
42     cp[ecnt] = 0;
43     first[v] = ecnt;
44 }
45 
46 void Spfa(){
47     fill(dis,dis + maxn,INF);
48     memset(pre,0,sizeof(pre));
49     memset(inq,0,sizeof(inq));
50     while(!Q.empty()) Q.pop();
51     Q.push(1);
52     inq[1] = 1;
53     dis[1] = 0;
54     while(!Q.empty()){
55         int x = Q.front(); Q.pop();
56         inq[x] = 0;
57         for(int i = first[x]; i != -1; i = next[i]){
58             int v = ver[i];
59             if(cp[i] == 0) continue;
60             if(dis[x] + cost[i] < dis[v]){
61                 dis[v] = dis[x] + cost[i];
62                 pre[v] = x;
63                 edge[v] = i;
64                 if(inq[v] == 0){
65                     inq[v] = 1;
66                     Q.push(v);
67                 }
68             }
69         }
70     }
71 }
72 
73 int MCMF(){
74     int min_cost = 0;
75     for(int t = 1; t <= 2; ++t){
76         Spfa();
77         for(int i = N; i != 1; i = pre[i]){
78             int id = edge[i];
79             cp[id] -= 1;
80             cp[(id & 1) ? id + 1 : id - 1] += 1;
81         }
82         min_cost += dis[N];
83     }
84     return min_cost;
85 }
86 
87 int main(){
88     int a,b,c;
89     Init();
90     scanf("%d%d",&N,&M);
91     for(int i = 1; i <= M; ++i){
92         scanf("%d%d%d",&a,&b,&c);
93         Add_edge(a,b,c);
94         Add_edge(b,a,c);
95     }
96     printf("%d\n",MCMF());
97     return 0;
98 }

 

posted @ 2014-12-22 00:40  Naturain  阅读(127)  评论(0编辑  收藏  举报