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
| #include <cstdio> #include <queue> #include <cstring>
const int INF = 1e9; inline int min(const int x, const int y) {return x < y ? x : y;} struct Edge { int to, nxt, cap; } e[800005]; int head[20005], cur[20005], num[20005], dep[20005], from[200005], to[200005], val[200005]; int tot = 1, s, t, n, m; std::queue<int> Q; inline void AddEdge(const int u, const int v, const int cap) { e[++ tot].to = v, e[tot].cap = cap, e[tot].nxt = head[u], head[u] = tot; }
void bfs() { memset(num, 0, sizeof num); memset(dep, 0, sizeof dep); memcpy(cur, head, sizeof cur); Q.push(t); num[dep[t] = 1] = 1; while (Q.size()) { int u(Q.front()); Q.pop(); for (int i(head[u]); i; i = e[i].nxt) if (!dep[e[i].to]) ++ num[dep[e[i].to] = dep[u] + 1], Q.push(e[i].to); } }
int dfs(const int u, const int flow) { if (u == t) return flow; int used(0), tmp(0); for (int i(head[u]); i; i = e[i].nxt) { cur[u] = i; if (dep[u] - 1 == dep[e[i].to] && e[i].cap) { if (tmp = dfs(e[i].to, min(e[i].cap, flow - used))) e[i].cap -= tmp, e[i ^ 1].cap += tmp, used += tmp; if (used == flow) return used; } } if (!(-- num[dep[u]])) dep[s] = n + 1; ++ num[++ dep[u]]; return used; }
int ISAP() { int Maxflow(0); bfs(); while (dep[s] && dep[s] <= n) Maxflow += dfs(s, INF); return Maxflow; }
int main() { int ans(0), L; scanf("%d%d", &n, &m); for (int i(1); i <= m; ++ i) scanf("%d%d%d", from + i, to + i, val + i); scanf("%d%d%d", &s, &t, &L); for (int i(1); i <= m; ++ i) if (val[i] < L) AddEdge(from[i], to[i], 1), AddEdge(to[i], from[i], 1); ans = ISAP(); memset(head, 0, sizeof head); tot = 1; for (int i(1); i <= m; ++ i) if (val[i] > L) AddEdge(from[i], to[i], 1), AddEdge(to[i], from[i], 1); printf("%d\n", ans + ISAP()); return 0; }
|