1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
| #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int INF = 1009999999;
int getint() {
int r = 0, k = 1; char c = getchar();
for (; '0' > c || c > '9'; c = getchar()) if (c == '-') k = -1;
for (; '0' <= c && c <= '9'; c = getchar()) r = r * 10 - '0' + c;
return r * k;
}
int A[20005], B[20005];
struct edge_type {
int to, next, r;
} edge[500005];
int S, T, cnte = 1, h[20005], d[20005], cur[20005], n, m;
bool vis[20005];
int Q[20005], tail, head, C[20005];
void ins(int u, int v, int f) {
edge[++cnte].to = v;
edge[cnte].next = h[u];
edge[cnte].r = f;
h[u] = cnte;
edge[++cnte].to = u;
edge[cnte].next = h[v];
edge[cnte].r = f;
h[v] = cnte;
}
bool bfs() {
tail = head = 0;
for (int i = 1; i <= n; ++i) d[i] = -1;
Q[tail++] = S;
d[S] = 0;
int now;
while (head < tail) {
now = Q[head++];
for (int i = h[now]; i; i = edge[i].next) {
if (d[edge[i].to] == -1 && edge[i].r) {
d[edge[i].to] = d[now] + 1;
Q[tail++] = edge[i].to;
}
}
}
return d[T] != -1;
}
int dfs(int now, int a) {
if (T == now || a == 0) return a;
int ret = 0, f;
for (int &i = cur[now]; i; i = edge[i].next) {
if (d[edge[i].to] != d[now]+1) continue;
if (f = dfs(edge[i].to, min(a, edge[i].r))) {
a -= f;
ret += f;
edge[i].r -= f;
edge[i^1].r += f;
if (a == 0) break;
}
}
if (ret == 0) d[now] = -1;
return ret;
}
void DFS(int now) {
vis[now] = 1;
for (int i = h[now]; i; i = edge[i].next) {
if (edge[i].r == 0 || vis[edge[i].to])
continue;
DFS(edge[i].to);
}
}
int ptr;
void init() {
for (int i = 2; i <= cnte; i += 2)
edge[i].r = edge[i^1].r = (edge[i].r + edge[i^1].r) >> 1;
}
void mincut(int l, int r) {
if (l >= r) return;
S = A[l]; T = A[r];
init();
int flow = 0;
while (bfs()) {
for (int i = 1; i <= n; ++i)
cur[i] = h[i];
flow += dfs(S, INF);
}
C[ptr++] = flow;
for (int i = 1; i <= n; ++i)
vis[A[i]] = 0;
DFS(S);
int L = l, R = r;
for (int i = l; i <= r; ++i) {
if (vis[A[i]]) {
B[L++] = A[i];
} else {
B[R--] = A[i];
}
}
for (int i = l; i <= r; ++i)
A[i] = B[i];
mincut(l, L - 1);
mincut(R + 1, r);
}
int main() {
n = getint(); m = getint();
for (int i = 1; i <= n; ++i)
A[i] = i;
int x, y, z;
for (int i = 1; i <= m; ++i) {
x = getint(); y = getint(); z = getint();
ins(x, y, z);
}
mincut(1, n);
sort(C, C+ptr);
int ans = 1;
for (int i = 1; i < ptr; ++i)
if (C[i] != C[i-1])
++ans;
printf("%d", ans);
return 0;
}
|