UVA1464 题解
将图建成圆方树后会发现,必经点数 = 圆方树上两点路径上圆点数。
考虑求路径中的圆点数量。因为起点和终点均为圆点,所以路径 \(x\) 到 \(y\) 的答案即为 \((dis(x,y)+1)/2\)。
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll mod = 1e9 + 7;
const int N = 200005;
const int INF = 0x3f3f3f3f;
int n, m;
int dfn[N], low[N], ck, cnt;
vector<int> G[N], H[N];
stack<int> s;
int vis[N], tot;
void tarjan(int u, int fa) {
dfn[u] = low[u] = ++ck;
vis[u] = tot;
s.push(u);
for (auto v : G[u]) {
if (!dfn[v]) {
tarjan(v, u);
low[u] = min(low[u], low[v]);
if (low[v] >= dfn[u]) {
cnt++;
while (1) {
int x = s.top();
s.pop();
H[cnt].push_back(x);
H[x].push_back(cnt);
if (x == v) break;
}
H[cnt].push_back(u);
H[u].push_back(cnt);
}
} else if (v != fa){
low[u] = min(low[u], dfn[v]);
}
}
}
int dep[N], fa[N], sz[N], son[N], top[N];
void dfs1(int u) {
dfn[u] = ++ck;
dep[u] = dep[fa[u]] + 1;
sz[u] = 1;
for (auto v : H[u]) {
if (v == fa[u]) continue;
fa[v] = u;
dfs1(v);
sz[u] += sz[v];
if (sz[v] > sz[son[u]]) son[u] = v;
}
}
void dfs2(int u, int h) {
top[u] = h;
if (son[u]) dfs2(son[u], h);
for (auto v : H[u]) {
if (v == fa[u] || v == son[u]) continue;
dfs2(v, v);
}
}
int LCA(int x, int y) {
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) swap(x, y);
x = fa[top[x]];
}
return dep[x] < dep[y] ? x : y;
}
int dis(int x, int y) {
if (vis[x] != vis[y]) return 0;
int ans = dep[x] + dep[y] - 2 * dep[LCA(x, y)];
ans = ans / 2 - 1;
return ans;
}
struct Node {
int x, y;
} bian[N];
int a[N];
int main() {
while (scanf("%d%d", &n, &m) != EOF) {
if (n == 0 && m == 0) break;
while (!s.empty()) {
s.pop();
}
for (int i = 1; i < N; i++) {
dfn[i] = low[i] = 0;
dep[i] = fa[i] = son[i] = sz[i] = top[i] = 0;
vis[i] = 0;
G[i].clear();
H[i].clear();
}
ck = 0;
tot = 0;
for (int i = 1; i <= m; i++) {
int u, v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
bian[i] = {u, v};
}
cnt = n;
for (int i = 1; i <= n; i++) {
if (!dfn[i]) {
tot++;
vis[i] = 1;
tarjan(i,-1);
dfs1(i);
dfs2(i, i);
}
}
ck = 0;
int q;
scanf("%d", &q);
while (q--) {
int x, y;
scanf("%d%d", &x, &y);
int a = bian[x].x, b = bian[x].y, c = bian[y].x, d = bian[y].y;
int ans = max(max(dis(b, d), dis(a, d)), max(dis(b, c), dis(a, c)));
// printf("#%d\n", LCA(a, b));
printf("%d\n", ans);
}
}
return 0;
}

浙公网安备 33010602011771号