SPOJ 4110 Fast Maximum Flow (最大流模板)

题目大意:

无向图,求最大流。

算法讨论:

Dinic可过。终于我的常数还是太大。以后要注意下了。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <algorithm>
 5 #include <iostream>
 6 #include <queue>
 7 using namespace std;
 8 typedef long long ll;
 9  
10 struct MF{
11   static const int N = 5000 + 5;
12   static const int M = 60000 + 5;
13   static const ll oo = 10000000000000LL;
14     
15   int n, m, s, t, tot, tim;
16   int first[N], next[M];
17   int u[M], v[M], cur[N], vi[N];
18     ll cap[M], flow[M], dis[N];
19   int que[N + N];
20   
21   void Clear(){
22     tot = 0;tim = 0;
23        for(int i = 1; i <= n; ++ i) first[i] = -1;
24   }
25   void Add(int from, int to, ll cp, ll flw){
26     u[tot] = from; v[tot] = to; cap[tot] = cp; flow[tot] = flw;
27     next[tot] = first[u[tot]];
28     first[u[tot]] = tot;
29     ++ tot;
30   }
31   bool bfs(){
32       ++ tim;
33     dis[s] = 0;vi[s] = tim;
34     
35     int head, tail;
36     head = tail = 1;
37     que[head] = s;
38     while(head <= tail){
39         for(int i = first[que[head]]; i != -1; i = next[i]){
40             if(vi[v[i]] != tim && cap[i] > flow[i]){
41                 vi[v[i]] = tim;
42                 dis[v[i]] = dis[que[head]] + 1;
43                     que[++ tail] = v[i];
44                 }
45             }
46             ++ head;
47         }
48        return vi[t] == tim;
49   }    
50   ll dfs(int x, ll a){
51     if(x == t || a == 0) return a;
52     ll flw = 0, f;
53     int &i = cur[x];
54     for(i = first[x]; i != -1; i = next[i]){
55       if(dis[x] + 1 == dis[v[i]] && (f = dfs(v[i], min(a, cap[i]-flow[i]))) > 0){
56         flow[i] += f; flow[i^1] -= f;
57           a -= f; flw += f;
58           if(a == 0) break;
59         }
60       }
61     return flw;
62   }
63     ll MaxFlow(int s, int t){
64     this->s = s;this->t = t;
65     ll flw = 0;
66     while(bfs()){
67       for(int i = 1; i <= n; ++ i) cur[i] = 0;
68       flw += dfs(s, oo);
69     }
70     return flw;
71   }
72 }Net;
73 int n, m;
74  
75 int main(){
76     int x, y;
77     ll z;
78     scanf("%d%d", &n, &m);
79     Net.n = n;
80     Net.Clear();
81     for(int i = 1; i <= m; ++ i){
82         scanf("%d%d%lld", &x, &y, &z);
83         Net.Add(x, y, z, 0);
84         Net.Add(y, x, z, 0);
85     }    
86     printf("%lld\n", Net.MaxFlow(1,Net.n));
87     return 0;
88 }
SPOJ 4110

 

转载于:https://www.cnblogs.com/sxprovence/p/5118761.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值