写了一万篇博客,懒得完善,就先不发了。。。
反正在自娱自乐没人看~~
发一篇网络流吧。
今天终于把Ford-Fulkerson升级成了dinic,省选网络流终于不用输出样例了(颓
先看看定义吧。。。
这是百度百科的说法,完全没用。
换个通俗点的解释吧。
初中物理电学还记得吧(膜参加省选的小学生)
现在电路上实现分流,你可以关闭导线或者调整电阻,使分流后到达用电器的电流最大(差不多,别较真了)
洛谷模板题
直接上dinic吧,反正还好理解(当初被无良辅导书坑的只会ek和Ford-Fulkerson的我欲哭无泪)
其实本质就是你在出发点灌水,bfs发现有一条路可以到达终点,然后就在这条路拼命灌水,直到达到最大值放不下而已。
有几点注意:
- 邻接表建造时留好去路,以便返回。
- 以层为目标建造一个数组,极大幅度节省时间(核心!!!!)
- 走不通的时候记得堵上,以免死循环……
直接上程序吧,毕竟第一讲说不了什么,还是理解第一啊:
1 #include <iostream>
2 #include <cstdlib>
3 #include <cstdio>
4 #include <cmath>
5 #include <vector>
6 #include <cstring>
7 #include <map>
8 #include <set>
9 #include <queue>
10 #include <algorithm>
11 using namespace std;
12 const int maxlongint = 2147483647;
13 int ans = 0, tot, n, m, st, ed;
14 int last[11000], h[11000];
15 struct edge{
16 int u, v, w, nxt, other;
17 }p[510000];
18 inline int read()
19 {
20 int s=0,w=1;
21 char ch=getchar();
22 while (ch<='0'||ch>'9')
23 {
24 if (ch=='-') w=-1;
25 ch=getchar();
26 }
27 while (ch>='0'&&ch<='9')
28 {
29 s=s*10+ch-'0';
30 ch=getchar();
31 }
32 return s*w;
33 }
34 void addedge(int u, int v, int w)
35 {
36 int k1, k2;
37 k1 = ++tot;
38 p[tot].u = u;
39 p[tot].v = v;
40 p[tot].w = w;
41 p[tot].nxt = last[u];
42 last[u] = tot;
43 k2 = ++tot;
44 p[tot].v = u;
45 p[tot].u = v;
46 p[tot].w = 0;
47 p[tot].nxt = last[v];
48 last[v] = tot;
49 p[k1].other = k2;
50 p[k2].other = k1;
51 }
52 bool bfs_h()
53 {
54 memset(h, 0, sizeof(h));
55 h[st] = true;
56 queue<int> q;
57 q.push(st);
58 while (! q.empty())
59 {
60 int u = q.front();
61 for (int k = last[u]; k > 0; k = p[k].nxt)
62 {
63 int v = p[k].v;
64 if (p[k].w>0 && h[v] == 0)
65 {
66 h[v] = h[u]+1;
67 q.push(v);
68 }
69 }
70 q.pop();
71 }
72 return h[ed];
73 }
74 int min(int x, int y)
75 {
76 if (x < y) return x;
77 else return y;
78 }
79 int findflow(int u, int f)
80 {
81 if (u == ed) return f;
82 int s = 0, t;
83 for (int k = last[u]; k>0; k = p[k].nxt)
84 {
85 int v = p[k].v;
86 if (p[k].w > 0 && h[v] == h[u]+1 && s < f)
87 {
88 t = findflow(v, min(p[k].w, f - s));
89 s += t;
90 p[k].w -= t;
91 p[p[k].other].w += t;
92 }
93 }
94 if (s == 0) h[u] = 0;
95 return s;
96 }
97 int main()
98 {
99 ios::sync_with_stdio(false);
100 //freopen(".in","r",stdin);
101 //freopen(".out","w",stdout);
102 n = read();
103 m = read();
104 st = read();
105 ed = read();
106 for (int i = 1; i <= m; i++)
107 {
108 int u, v, w;
109 u = read();
110 v = read();
111 w = read();
112 addedge(u, v, w);
113 }
114 while (bfs_h())
115 ans += findflow(st, maxlongint);
116 cout << ans;
117 return 0;
118 }
程序不算长(相对吧。。。),注意吃透。