UVA-12363 Hedge Mazes
Hedge Mazes
判断两点之间是不是只有唯一一条简单路径
tarjan 割边
如果两点之间仅有一条简单路径,说明如果将路径上的一条边割掉,则两点之间不连通,换句话说,这条最短路径上的所有边都是割边
因此考虑找出所有的割边,用割边来跑一次并查集
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 2e5 + 10;
int head[maxn], nexx[maxn], to[maxn], vp = 0;
int dfn[maxn], low[maxn], top[maxn], tp = 0;
int cut[maxn];
void init(int n)
{
for(int i=0; i<=n; i++) head[i] = dfn[i] = low[i] = 0;
for(int i=0; i<=n; i++) top[i] = i;
for(int i=0; i<=vp; i++) cut[i] = 0;
vp = 1;
}
inline void add(int u, int v)
{
vp++;
nexx[vp] = head[u];
head[u] = vp;
to[vp] = v;
}
int query(int x)
{
return x == top[x] ? x : top[x] = query(top[x]);
}
void tarjan(int now, int pre)
{
dfn[now] = low[now] = ++tp;
for(int i=head[now]; i; i=nexx[i])
{
int nex = to[i];
if(dfn[nex] == 0)
{
tarjan(nex, i);
low[now] = min(low[nex], low[now]);
if(low[nex] > dfn[now])
cut[i] = 1;
}
else if(i != (pre ^ 1))
low[now] = min(low[now], dfn[nex]);
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, m, q;
while(cin >> n >> m >> q && (n | m | q))
{
init(n);
while(m--)
{
int a, b;
cin >> a >> b;
add(a, b);
add(b, a);
}
for(int i=1; i<=n; i++)
if(dfn[i] == 0) tarjan(i, -1);
for(int i=1; i<=n; i++)
{
for(int j=head[i]; j; j=nexx[j])
{
if(cut[j] == 0) continue;
int nex = to[j];
int a = query(i), b = query(nex);
if(a != b) top[a] = top[b];
}
}
while(q--)
{
int a, b;
cin >> a >> b;
int aa = query(a), bb = query(b);
if(top[aa] == top[bb]) cout << "Y\n";
else cout << "N\n";
}
cout << "-\n";
}
// cout << endl;
return 0;
}