#include <cstdio> #include <algorithm> #include <vector> #include <iostream> #include <queue> #include <cstring> using namespace std; const int INF = 0x3f3f3f3f; const int MAX_N = 2E4 + 10; const int MAX_M = 2E5 + 10; int N, M, A[MAX_N], B[MAX_N], b[MAX_M], a[MAX_M], w[MAX_M]; struct Edge { int from, to, cap, flow; Edge(int from, int to, int cap, int flow): from(from), to(to), cap(cap), flow(flow) {} }; struct Dinic { int n, m, s, t; vector<Edge>edges; vector<int>G[MAX_N]; bool vis[MAX_N]; int d[MAX_N], cur[MAX_N]; void add_edge(int from, int to, int cap) { edges.push_back(Edge(from, to, cap, 0)); edges.push_back(Edge(to, from, 0, 0)); m = edges.size(); G[from].push_back(m - 2); G[to].push_back(m - 1); } bool BFS() { memset(vis, 0, sizeof(vis)); queue<int>Q; Q.push(s); d[s] = 0; vis[s] = 1; while (!Q.empty()) { int x = Q.front(); Q.pop(); for (int i = 0; i < G[x].size(); i++) { Edge &e = edges[G[x][i]]; if (!vis[e.to] && e.cap > e.flow) { vis[e.to] = 1; d[e.to] = d[x] + 1; Q.push(e.to); } } } return vis[t]; } int DFS(int x, int a) { if (x == t || a == 0) return a; int flow = 0, f; for (int &i = cur[x]; i < G[x].size(); i++) { Edge &e = edges[G[x][i]]; if (d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow))) > 0) { e.flow += f; edges[G[x][i] ^ 1].flow -= f; flow += f; a -= f; if (a == 0) break; } } return flow; } int max_flow(int s, int t) { this->s = s; this->t = t; int flow = 0; while (BFS()) { memset(cur, 0, sizeof(cur)); flow += DFS(s, INF); } return flow; } }; Dinic D; void solve() { int s = N, t = s + 1; for (int i = 0; i < N; i++) D.add_edge(i, t, A[i]), D.add_edge(s, i, B[i]); for (int i = 0; i < M; i++) D.add_edge(a[i] - 1, b[i] - 1, w[i]), D.add_edge(b[i] - 1, a[i] - 1, w[i]); printf("%d\n", D.max_flow(s, t)); } int main(int argc, char const *argv[]) { while (~scanf("%d%d", &N, &M) && N + M) { for (int i = 0; i < N; i++) scanf("%d%d", &A[i], &B[i]); for (int i = 0; i < M; i++) scanf("%d%d%d", &a[i], &b[i], &w[i]); solve(); } return 0; }
这道题目白书上有题解,可惜他的算法过不了时限。。。。。
需要用刘汝佳的算法,Dinic和ISAP都可以。