题意:
一个无向图,每次查询两个点s和t,判断是否s到t间存在且只存在一条简单路径。
题解:
若只存在一条简单路径,那么删掉路径上任意一条边,s和t 都变得不可达,也就是说路径上的边都是桥边。那么如果删掉所有非桥边,符合条件的点对就必须在同一个连通分量里。
//Time:126ms
//Memory:1775B
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
const int MAXN = 200010;
using namespace std;
bool ty[MAXN];
int he[MAXN],to[MAXN],nex[MAXN],top,bel[MAXN],now,btop;
int dfn[MAXN],low[MAXN];
void add(int u,int v)
{
to[top]=v;
nex[top]=he[u];
he[u]=top++;
}
void tarjan(int h,int pre)
{
dfn[h]=low[h]=++now;
for(int i=he[h];i!=-1;i=nex[i])
if((i^1)!=pre)
{
if(!dfn[to[i]])
{
tarjan(to[i],i);
low[h]=min(low[to[i]],low[h]);
if(dfn[h]<low[to[i]]) ty[i]=ty[i^1]=1;
}
else low[h]=min(low[h],dfn[to[i]]);
}
}
void bfs(int h)
{
queue<int> que;
que.push(h);
++btop;
bel[h]=btop;
while(que.size())
{
h=que.front();
que.pop();
for(int i=he[h];i!=-1;i=nex[i])
if(ty[i]&&!bel[to[i]])
bel[to[i]]=btop,que.push(to[i]);
}
}
int main()
{
//freopen("/home/moor/Code/input","r",stdin);
int n,m,q;
while(scanf("%d%d%d",&n,&m,&q)&&n&&m&&q)
{
int u,v;
top=0;
btop=1;
now=1;
memset(dfn,0,sizeof(dfn));
memset(bel,0,sizeof(bel));
memset(ty,0,sizeof(ty));
memset(he,-1,sizeof(he));
for(int i=0;i<m;++i)
{
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
for(int i=1;i<=n;++i)
if(!dfn[i])
tarjan(i,-1);
for(int i=1;i<=n;++i)
if(!bel[i])
bfs(i);
for(int i=0;i<q;++i)
{
scanf("%d%d",&u,&v);
printf("%c\n",bel[u]==bel[v]?'Y':'N');
}
printf("-\n");
}
return 0;
}