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
| #include <cstdio> #include <cstring> #include <queue>
using namespace std;
const int N = 125100; int n, m, s, t, tot = 1, hd[(int)6e4], cur[(int)6e4], ss, tt, dep[(int)6e4]; long long flow[(int)6e4], l[N]; struct Edge { int to, nxt; long long val; } e[N * 3 + 99]; inline void add(int u, int v, long long w) { e[++tot] = {v, hd[u], w}, hd[u] = tot; e[++tot] = {u, hd[v], 0ll}, hd[v] = tot; }
bool bfs(int st, int en) { for (int i = 0; i <= n + 2; ++i) dep[i] = 0; queue<int> q; memcpy(cur, hd, sizeof(hd)); q.push(st); dep[st] = 1;
while (!q.empty()) { int u = q.front(); q.pop(); for (int eg = hd[u]; eg; eg = e[eg].nxt) { if (!dep[e[eg].to] && e[eg].val > 0) { dep[e[eg].to] = dep[u] + 1; q.push(e[eg].to); } } } return !!dep[en]; }
long long dfs(int u, int en, long long flow) { if (u == en) return flow; long long r = flow; for (int eg = cur[u]; eg && r; eg = e[eg].nxt) { cur[u] = eg; if (e[eg].val > 0 && dep[e[eg].to] == dep[u] + 1) { long long c = dfs(e[eg].to, en, min(r, e[eg].val)); r -= c; e[eg].val -= c; e[eg ^ 1].val += c; } } return flow - r; }
long long Dinic(int st, int en) { long long ret = 0; while (bfs(st, en)) ret += dfs(st, en, 1ll << 53); return ret; }
int main() { long long tmp, sum = 0; scanf("%d%d%d%d", &n, &m, &s, &t); tt = n + 1; for (int i = 1, w, x; i <= m; ++i) { long long y, z; scanf("%d%d%lld%lld", &w, &x, &y, &z); l[i] = y; add(w, x, z - y); flow[w] -= l[i], flow[x] += l[i]; } for (int i = 1; i <= n; ++i) { if (flow[i] > 0) { sum += flow[i]; add(ss, i, flow[i]); } else if (flow[i] < 0) add(i, tt, -flow[i]); } add(t, s, 1ll << 53); if (sum == Dinic(ss, tt)) { tmp = e[tot].val; e[tot].val = e[tot ^ 1].val = 0; printf("%lld\n", tmp + Dinic(s, t)); } else puts("please go home to sleep"); return 0; }
|