P3163 [CQOI2014] 危桥

cxqghzj·2023-12-10 16:42·7 次阅读

P3163 [CQOI2014] 危桥

题意#

给定一张无向图。其中某些边只能走 2 次。

你要从 a1 走到 a2 an 次,b1 走到 b2 bn 次。

问是否能实现。

Sol#

不难想到连边跑网络流。

但是,只能走 2 次的限制无法满足。

注意到是无向图,所以我们交换其中一个起点终点。

不难发现这样过后,矛盾的贡献就不产生了。

Code#

Copy
#include <iostream> #include <algorithm> #include <cstdio> #include <array> #include <queue> #define int long long #define pii pair <int, int> using namespace std; // #ifdef ONLINE_JUDGE // #define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++) // char buf[1 << 23], *p1 = buf, *p2 = buf, ubuf[1 << 23], *u = ubuf; // #endif int read() { int p = 0, flg = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') flg = -1; c = getchar(); } while (c >= '0' && c <= '9') { p = p * 10 + c - '0'; c = getchar(); } return p * flg; } void write(int x) { if (x < 0) { x = -x; putchar('-'); } if (x > 9) { write(x / 10); } putchar(x % 10 + '0'); } #define fi first #define se second const int N = 205, M = 5e3 + 5, inf = 2e18; namespace G { array <int, N> fir; array <int, M> nex, to, cap; int cnt = 1; void add(int x, int y, int z) { cnt++; nex[cnt] = fir[x]; to[cnt] = y; cap[cnt] = z; fir[x] = cnt; } void _add(int x, int y, int z) { add(x, y, z); add(y, x, z); } } namespace Mfl { array <int, N> dis, cur; queue <int> q; bool bfs(pii st) { dis.fill(-1), dis[st.fi] = 0; q.push(st.fi); while (!q.empty()) { int u = q.front(); q.pop(); for (int i = G::fir[u]; i; i = G::nex[i]) { if (G::cap[i] <= 0 || ~dis[G::to[i]]) continue; dis[G::to[i]] = dis[u] + 1; q.push(G::to[i]); } } return ~dis[st.se]; } int dfs(int x, int augcd, pii st) { if (x == st.se) return augcd; int augc = augcd; for (int &i = cur[x]; i; i = G::nex[i]) { int flow = G::cap[i]; if (flow <= 0 || dis[G::to[i]] <= dis[x]) continue; int del = dfs(G::to[i], min(augc, flow), st); augc -= del; G::cap[i] -= del, G::cap[i ^ 1] += del; if (augc <= 0) break; } return augcd - augc; } int dinic(pii st) { int ans = 0; while (bfs(st)) { copy(G::fir.begin(), G::fir.end(), cur.begin()); // cur = G::fir; ans += dfs(st.fi, inf, st); } return ans; } } char strbuf[N][N]; signed main() { // while () int n, a1, a2, a3, b1, b2, b3; while (~scanf("%lld%lld%lld%lld%lld%lld%lld", &n, &a1, &a2, &a3, &b1, &b2, &b3)) { a1++, a2++, b1++, b2++; G::fir.fill(0), G::cnt = 1; pii st = make_pair(n + 1, n + 2); for (int i = 1; i <= n; i++) { scanf("%s", strbuf[i] + 1); for (int j = i + 1; j <= n; j++) { if (strbuf[i][j] == 'X') continue; if (strbuf[i][j] == 'O') G::_add(i, j, 1); else G::_add(i, j, inf); } } G::_add(st.fi, a1, a3), G::_add(a2, st.se, a3); G::_add(st.fi, b1, b3), G::_add(b2, st.se, b3); int ans = Mfl::dinic(st); G::fir.fill(0), G::cnt = 1; for (int i = 1; i <= n; i++) { for (int j = i + 1; j <= n; j++) { if (strbuf[i][j] == 'X') continue; if (strbuf[i][j] == 'O') G::_add(i, j, 1); else G::_add(i, j, inf); } } G::_add(st.fi, a1, a3), G::_add(a2, st.se, a3); G::_add(st.fi, b2, b3), G::_add(b1, st.se, b3); if (Mfl::dinic(st) == ans && ans == a3 + b3) puts("Yes"); else puts("No"); } return 0; }
posted @   cxqghzj  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
目录