我的想法是tarjan求割点之后,从起点到终点dfs,收集路径上的割点,然后输出最小的那个。但是在某测试点WA了。
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <stack>
#include <utility>
#include <vector>
using namespace std;
const int N = 110, M = N * N;
int h[N], nxt[M], e[M], idx = 1;
int n, a, b;
int low[N], dfn[N], stmp;
bool is_cut[N], vis[N];
vector<int> cuts;
stack<int> s;
void add(int a, int b) {
e[idx] = b, nxt[idx] = h[a], h[a] = idx++;
}
void tarjan(int u, int root) {
dfn[u] = low[u] = ++stmp;
s.push(u);
int child = 0;
for (int i = h[u]; i; i = nxt[i]) {
int j = e[i];
if (!dfn[j]) {
tarjan(j, root);
low[u] = min(low[u], low[j]);
child += u == root;
if (low[j] >= dfn[u]) {
is_cut[u] |= u != root || child > 1;
int y;
bool flag = false;
auto check = [&](int x) {
if ((x == a || x == b) && exchange(flag, true)) {
puts("No solution");
exit(0);
}
};
do {
y = s.top();
s.pop();
check(y);
} while (y != j);
check(u);
}
}
else
low[u] = min(low[u], dfn[j]);
}
}
int dfs(int u) {
vis[u] = true;
if (u == b)
return *min_element(cuts.begin(), cuts.end());
if (is_cut[u])
cuts.push_back(u);
for (int i = h[u]; i; i = nxt[i]) {
int j = e[i];
if (!vis[j]) {
int res = dfs(j);
if (res != -1)
return res;
}
}
if (is_cut[u])
cuts.pop_back();
return -1;
}
int main() {
#ifndef ONLINE_JUDGE
freopen(".in", "r", stdin);
// freopen(".out", "w", stdout);
#else
cin.tie(0)->sync_with_stdio(0);
#endif
scanf("%d", &n);
while (scanf("%d %d\n", &a, &b) && a)
add(a, b), add(b, a);
scanf("%d %d", &a, &b);
tarjan(a, a);
printf("%d", dfs(a));
return 0;
}