edge e[20007]; int mxf[1007], pre[1007], h[1007], ecnt; // mxf[i]代表节点i的输入流量,pre记录路径 int n, m, s, t, maxflow;
intbfs() { memset(mxf, 0, sizeof(mxf)); int u, v, c; queue <int> q; q.push(s), mxf[s] = inf; while (!q.empty()) { u = q.front(); q.pop(); if (u == t) return1; for (int i = h[u]; i != -1; i = e[i].nx) { v = e[i].v, c = e[i].c; if (mxf[v] == 0 && c) { mxf[v] = min(mxf[u], c); pre[v] = i; q.push(v); } } } return0; }
voidadd(int u, int v, int w) { e[ecnt].nx = h[u]; e[ecnt].v = v; e[ecnt].c = w; h[u] = ecnt; ++ ecnt; }
intmain() { cin >> n >> m >> s >> t; for (int i = 1; i <= n; ++ i) h[i] = -1; for (int i = 1, u, v, w; i <= m; ++ i) { cin >> u >> v >> w; add(u, v, w), add(v, u, 0); } while (bfs()) // bfs寻找增广路,找不到就说明增广路寻找 { int v = t; while (v != s) // 反向边 { int i = pre[v]; e[i].c -= mxf[t]; e[i ^ 1].c += mxf[t]; v = e[i ^ 1].v; } maxflow += mxf[t]; // 更新最大流 } cout << maxflow; return0; }
intbfs() { memset(d, 0, sizeof d); int u, v, c; queue <int> q; q.push(s), d[s] = 1; while (!q.empty()) { u = q.front(); q.pop(); if (u == t) return1; for (int i = h[u]; i != -1; i = e[i].nx) { v = e[i].v, c = e[i].c; if (d[v] == 0 && c) { d[v] = d[u] + 1; // 建立分层图 q.push(v); } } } return0; }
LL dfs(LL u, LL mf) { if (u == t) return mf; LL sum = 0, v, c, flow; for (int i = cur[u]; i != -1; i = e[i].nx) { cur[u] = i; // 当前弧优化 v = e[i].v, c = e[i].c; if (d[v] == d[u] + 1 && c) { flow = dfs(v, min(mf, c)); e[i].c -= flow; // 退流操作 e[i ^ 1].c += flow; sum += flow; mf -= flow; if (mf == 0) break; // 剩余流量优化 } } if (sum == 0) d[u] = 0; // 残枝优化 return sum; }
intmain() { cin >> n >> m >> s >> t; for (int i = 1; i <= n; ++ i) h[i] = -1; for (int i = 1, u, v, w; i <= m; ++ i) { cin >> u >> v >> w; add(u, v, w), add(v, u, 0); } while (bfs()) // 建立分层图和检查增广路 { memcpy(cur, h, sizeof h); // 每轮分层图初始化cur maxflow += dfs(s, inf); // 更新最大流 } cout << maxflow; return0; }
一共有 n 个飞行员,其中有 m 个外籍飞行员和 (n−m) 个英国飞行员,外籍飞行员从 1 到 m 编号,英国飞行员从 m+1 到 n 编号。 对于给定的外籍飞行员与英国飞行员的配合情况,试设计一个算法找出最佳飞行员配对方案,使皇家空军一次能派出最多的飞机。
输入的第一行是用空格隔开的两个正整数,分别代表外籍飞行员的个数 m 和飞行员总数 n。
从第二行起到倒数第二行,每行有两个整数 u,v,代表外籍飞行员 u 可以和英国飞行员 v 配合。
输入的最后一行保证为 -1 -1,代表输入结束。
本题存在 Special Judge。
请输出能派出最多的飞机数量,并给出一种可行的方案。
输出的第一行是一个整数,代表一次能派出的最多飞机数量,设这个整数是 k。
第 2 行到第 k+1 行,每行输出两个整数 u,v,代表在你给出的方案中,外籍飞行员 u 和英国飞行员 v 配合。这 k 行的 u 与 v 应该互不相同。
int m, n; int h[107], d[107], cur[107], cnt, vis[107], maxflow;
voidadd(int u, int v, int w) { e[cnt] = {v, w, h[u]}; h[u] = cnt ++; }
intbfs() { memset(d, 0, sizeof d); int u, v, c; queue <int> q; q.push(0), d[0] = 1; while (!q.empty()) { u = q.front(); q.pop(); if (u == n + 1) return1; for (int i = h[u]; i != -1; i = e[i].nx) { v = e[i].v, c = e[i].c; if (d[v] == 0 && c) { d[v] = d[u] + 1; q.push(v); } } } return0; }
intdfs(int u, int mf) { if (u == n + 1) return mf; int sum = 0, v, c, flow; for (int i = cur[u]; i != -1; i = e[i].nx) { cur[u] = i; v = e[i].v, c = e[i].c; if (d[v] == d[u] + 1 && c) { flow = dfs(v, min(mf, c)); e[i].c -= flow; e[i ^ 1].c += flow; sum += flow; mf -= flow; if (mf == 0) break; } } if (sum == 0) d[u] = 0; return sum; }
intmain() { cin >> m >> n; for (int i = 0; i <= n; ++ i) h[i] = -1; while (1) { int u, v; cin >> u >> v; if (u == -1 && v == -1) break; add(u, v, 1), add(v, u, 0); if (!vis[u]) vis[u] = 1, add(0, u, 1), add(u, 0, 0); if (!vis[v]) vis[v] = 1, add(v, n + 1, 1), add(n + 1, v, 0); } while (bfs()) { memcpy(cur, h, sizeof h); maxflow += dfs(0, inf); } cout << maxflow << '\n'; for (int i = 1; i < cnt; i += 2) { if (e[i].v != 0 && e[i].v != n + 1 && e[i ^ 1].v != 0 && e[i ^ 1].v != n + 1 && e[i].c) cout << e[i].v << ' ' << e[i ^ 1].v << '\n'; } return0; }
现有 n 个太空站位于地球与月球之间,且有 m 艘公共交通太空船在其间来回穿梭。每个太空站可容纳无限多的人,而太空船的容量是有限的,第 i 艘太空船只可容纳 hi 个人。每艘太空船将周期性地停靠一系列的太空站,例如 (1,3,4) 表示该太空船将周期性地停靠太空站 134134134…。每一艘太空船从一个太空站驶往任一太空站耗时均为 1。人们只能在太空船停靠太空站(或月球、地球)时上、下船。
int n, m, s = 0, t, k, ss = 30005, tt = 30006; int h[30007], d[30007], cur[30007], cnt, maxflow; int hh[107], r[107]; int fa[107]; vector <int> ship[107];
intfind(int x){ return fa[x] == x ? x : fa[x] = find(fa[x]); }
voidadd(int u, int v, int w) { e[cnt] = {v, w, h[u]}; h[u] = cnt ++; }
intbfs() { memset(d, 0, sizeof d); int u, v, c; queue <int> q; q.push(ss), d[ss] = 1; while (!q.empty()) { u = q.front(); q.pop(); for (int i = h[u]; i != -1; i = e[i].nx) { v = e[i].v, c = e[i].c; if (d[v] == 0 && c) { d[v] = d[u] + 1; q.push(v); if (v == tt) return1; } } } return0; }
intdfs(int u, int mf) { if (u == tt) return mf; int sum = 0, v, c, flow; for (int i = cur[u]; i != -1; i = e[i].nx) { cur[u] = i; v = e[i].v, c = e[i].c; if (d[v] == d[u] + 1 && c) { flow = dfs(v, min(mf, c)); e[i].c -= flow; e[i ^ 1].c += flow; sum += flow; mf -= flow; if (mf == 0) break; } } if (sum == 0) d[u] = 0; return sum; }
intmain() { cin >> n >> m >> k; t = n + 1; memset(h, -1, sizeof h); for (int i = 0; i <= 20; ++ i) fa[i] = i; for (int i = 1; i <= m; ++ i) { cin >> hh[i] >> r[i]; for (int j = 1, sta; j <= r[i]; ++ j) { cin >> sta; ship[i].push_back(sta); } } for (int i = 0; i < 1000; ++ i) for (int j = 0; j <= n + 1; ++ j) { add(j + i * (n + 2), j + (i + 1) * (n + 2), inf), add(j + (i + 1) * (n + 2), j + i * (n + 2), 0); if (j == s) add(ss, s + i * (n + 2), inf), add(s + i * (n + 2), ss, 0); if (j == n + 1) add(t + i * (n + 2), tt, inf), add(tt, t + i * (n + 2), 0); } int tm = 0; while (++ tm) { for (int i = 1; i <= m; ++ i) { int lst = ship[i][(tm - 1) % r[i]], now = ship[i][tm % r[i]]; if (lst == -1) lst = t; if (now == -1) now = t; add(lst + ((tm - 1) * (n + 2)), now + (tm * (n + 2)), hh[i]), add(now + (tm * (n + 2)), lst + ((tm - 1) * (n + 2)), 0); if (find(lst) != find(now)) fa[now] = lst; while (bfs()) { memcpy(cur, h, sizeof h); maxflow += dfs(ss, inf); } } if (maxflow >= k) break; if (tm > 50) { for (int i = 0; i <= n; ++ i) find(i); find(t); for (int i = 0; i <= n; ++ i) if (fa[i] != fa[0]) { cout << 0; return0; } if (fa[t] != fa[0]) { cout << 0; return0; } } } cout << tm; return0; }