网络流
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cctype> #include <algorithm> using namespace std; int read() { int x = 0, f = 1; char c = getchar(); while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); } while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); } return x * f; } #define maxn 1000010 #define maxm 8000010 #define oo 2147483647 #define LL long long struct Edge { int from, to, flow; Edge() {} Edge(int _1, int _2, int _3): from(_1), to(_2), flow(_3) {} } ; struct Dinic { int n, m, s, t, head[maxn], nxt[maxm]; Edge es[maxm]; int vis[maxn], Q[maxn], hd, tl; int cur[maxn]; void init() { m = 0; memset(head, -1, sizeof(head)); return ; } void setn(int _n) { n = _n; return ; } void AddEdge(int a, int b, int c) { es[m] = Edge(a, b, c); nxt[m] = head[a]; head[a] = m++; es[m] = Edge(b, a, 0); nxt[m] = head[b]; head[b] = m++; return ; } bool BFS() { memset(vis, 0, sizeof(vis)); vis[t] = 1; hd = tl = 0; Q[++tl] = t; while(hd < tl) { int u = Q[++hd]; for(int i = head[u]; i != -1; i = nxt[i]) { Edge& e = es[i^1]; if(!vis[e.from] && e.flow) { vis[e.from] = vis[u] + 1; Q[++tl] = e.from; } } } return vis[s] > 1; } int DFS(int u, int a) { if(u == t || !a) return a; int flow = 0, f; for(int& i = cur[u]; i != -1; i = nxt[i]) { Edge& e = es[i]; if(vis[e.to] == vis[u] - 1 && (f = DFS(e.to, min(a, e.flow)))) { flow += f; a -= f; e.flow -= f; es[i^1].flow += f; if(!a) return flow; } } return flow; } LL MaxFlow(int _s, int _t) { s = _s; t = _t; LL flow = 0; while(BFS()) { for(int i = 1; i <= n; i++) cur[i] = head[i]; flow += DFS(s, oo); } return flow; } } sol; int main() { int n = read(), m = read(), s = read(), t = read(); sol.init(); sol.setn(n); for(int i = 1; i <= m; i++) { int a = read(), b = read(), c = read(); sol.AddEdge(a, b, c); } printf("%lld\n", sol.MaxFlow(s, t)); return 0; }
#include <bits/stdc++.h> using namespace std; #define rep(i, s, t) for(int i = (s), mi = (t); i <= mi; i++) #define dwn(i, s, t) for(int i = (s), mi = (t); i >= mi; i--) int read() { int x = 0, f = 1; char c = getchar(); while(!isdigit(c)) { if(c == '-') f = -1; c = getchar(); } while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); } return x * f; } #define maxn 500010 #define maxm 500010 #define oo 2147483647 namespace ZKW { struct Edge { int from, to, flow, cost; Edge() {} Edge(int _1, int _2, int _3, int _4): from(_1), to(_2), flow(_3), cost(_4) {} } es[maxm]; int n, m, s, t, ans, cost, head[maxn], nxt[maxm]; int Q[maxn], hd, tl, d[maxn]; bool inq[maxn]; bool vis[maxn]; void init() { ans = 0; m = 0; memset(head, -1, sizeof(head)); return ; } void clearFlow() { for(int i = 0; i < m; i += 2) es[i].flow += es[i^1].flow, es[i^1].flow = 0; return ; } void AddEdge(int a, int b, int c, int d) { es[m] = Edge(a, b, c, d); nxt[m] = head[a]; head[a] = m++; es[m] = Edge(b, a, 0, -d); nxt[m] = head[b]; head[b] = m++; return ; } int Nxt(int x) { return (x + 1) % maxn; } bool BFS() { rep(i, 1, n) d[i] = oo; d[t] = 0; hd = tl = 0; Q[tl = Nxt(tl)] = t; inq[t] = 1; while(hd != tl) { int u = Q[hd = Nxt(hd)]; inq[u] = 0; for(int i = head[u]; i != -1; i = nxt[i]) { Edge &e = es[i^1]; if(e.flow && d[e.from] > d[u] + e.cost) { d[e.from] = d[u] + e.cost; if(!inq[e.from]) inq[e.from] = 1, Q[tl = Nxt(tl)] = e.from; } } } if(d[s] == oo) return 0; cost = d[s]; return 1; } int DFS(int u, int a) { if(u == t || !a) return ans += cost * a, a; if(vis[u]) return 0; vis[u] = 1; int flow = 0, f; for(int i = head[u]; i != -1; i = nxt[i]) { Edge &e = es[i]; if(d[e.to] == d[u] - e.cost && (f = DFS(e.to, min(a, e.flow)))) { flow += f; a -= f; e.flow -= f; es[i^1]. flow += f; if(!a) return flow; } } return flow; } int MaxFlow(int _s, int _t) { s = _s; t = _t; int flow = 0, f; while(BFS()) do { memset(vis, 0, sizeof(int) * (n + 1)); f = DFS(s, oo); flow += f; } while(f); return flow; } } using ZKW::AddEdge; int main() { int n = read(), m = read(); ZKW::init(); ZKW::n = n; rep(i, 1, m) { int a = read(), b = read(), c = read(), d = read(); AddEdge(a, b, c, d); } printf("%d ", ZKW::MaxFlow(1, n)); printf("%d\n", ZKW::ans); return 0; }