题目链接:HDU-4280 Island Transport
题意
给出$n$个岛屿$m$条双向航道,岛屿以直角坐标系上的坐标形式给出,每条航道在单位时间有运输量上限,问单位时间内从$x$轴最左边的岛屿到最右边的岛屿最大的运输量。
思路
最大流问题,最左边的岛屿为源点,最右边的岛屿为汇点,按所给航道连边即可,由于是无向边,所以不需要再建容量为0的反向边。$n,m$很大,要用效率较高的Dinic算法求解最大流。
代码实现
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #define RG register #define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++) using std::queue; const int INF = 0x3f3f3f3f, N = 100010, M = 200020; int head[N], d[N]; int s, t, tot, maxflow; struct Edge { int to, cap, nex; } edge[M]; queue<int> q; char B[1 << 15], *S = B, *T = B; inline int read() { RG char ch; RG int x = 0; RG bool m = 0; while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ; ch == '-' ? m = 1 : x = ch - '0'; while (ch = getc(), ch >= '0' && ch <= '9') x = x * 10 + ch - '0'; return m ? -x : x; } void add(int x, int y, int z) { edge[++tot].to = y, edge[tot].cap = z, edge[tot].nex = head[x], head[x] = tot; //edge[++tot].to = x, edge[tot].cap = 0, edge[tot].nex = head[y], head[y] = tot; } bool bfs() { memset(d, 0, sizeof(d)); while (q.size()) q.pop(); q.push(s); d[s] = 1; while (q.size()) { int x = q.front(); q.pop(); for (int i = head[x]; i; i = edge[i].nex) { int v = edge[i].to; if (edge[i].cap && !d[v]) { q.push(v); d[v] = d[x] + 1; if (v == t) return true; } } } return false; } int dinic(int x, int flow) { if (x == t) return flow; int rest = flow, k; for (int i = head[x]; i && rest; i = edge[i].nex) { int v = edge[i].to; if (edge[i].cap && d[v] == d[x] + 1) { k = dinic(v, std::min(rest, edge[i].cap)); if (!k) d[v] = 0; edge[i].cap -= k; edge[i^1].cap += k; rest -= k; } } return flow - rest; } void init() { tot = 1, maxflow = 0; memset(head, 0, sizeof(head)); } int main() { int T = read(); while (T--) { init(); int n = read(), m = read(); int xx, yy, lx = INF, rx = -INF; for (int i = 0; i < n; i++) { xx = read(), yy = read(); if (xx < lx) lx = xx, s = i + 1; if (xx > rx) rx = xx, t = i + 1; } for (int i = 0, u, v, z; i < m; i++) { u = read(), v = read(), z = read(); add(u, v, z); add(v, u, z); } while (bfs()) maxflow += dinic(s, INF); printf("%d ", maxflow); } return 0; }