Freda是一個迷宮愛好者,她利用業餘時間建造了許多迷宮。每一個迷宮都是由若干房間和走廊構成的,每條走廊都鏈接着兩個不一樣的房間,兩個房間之間最多隻有一條走廊直接相連,走廊都是雙向經過。
黃昏時候,Freda喜歡在迷宮當中漫步。天天,Resodo都會爲Freda設計一個挑戰方案。Resodo會指定起點和終點,請Freda來找到一條從起點到終點的簡單路徑。一條簡單路徑定義爲一個房間序列,每一個房間至多在序列裏出現一次,且序列中相鄰的兩個房間有走廊相連。當起點和終點之間存在且僅存在一條簡單路徑的時候,Freda認爲這個挑戰方案是RD的。如今,請你幫幫Resodo來寫一個程序,判斷一個挑戰方案是不是RD的。spa
第一行三個整數N,M,Q.分別表示房間數,走廊數,詢問數。
接下來M行每行2個整數x,y, 0<x,y<=N, 表示x和y之間有一條走廊相連。
接下來Q行每行2個整數x,y, 表示詢問以x爲起點,y爲終點的挑戰方案是不是RD的.設計
對於每一個詢問,輸出一行」Y」或者」N」(不含引號).Y表示該詢問所表示的挑戰方案是RD的,N表示該詢問所表示的挑戰方案不是RD的.
輸入樣例
6 5 3
1 2
2 3
2 4
2 5
4 5
1 3
1 5
2 6
輸出樣例
Y
N
N
提示
樣例解釋
1,3之間只有一條路徑 1->2->3
1,5之間有兩條路徑 1->2->5 ; 1->2->4->5
1,6之間沒有路徑
數據範圍與約定
對於30%的數據,N<=100, M<=1000, Q<=100.
對於50%的數據,N<=1000, M<=10000, Q<=1000.
對於100%的數據,N<=10000, M<=100000, Q<=10000.code
分析blog
最近智商真的是愈來愈低了,一個題想了半天(感受CSP藥丸?it
兩個點之間只存在一條簡單路徑,那麼這條路徑上全部的邊必定都是原圖中的橋(割邊),否則這些邊之間就存在環,這些邊就能夠由其它邊代替io
因而就想了半天如何判斷路徑中只含割邊class
其實只須要將全部割邊求出來而後只連割邊,在同一個連通塊裏的點之間的路徑就是隻含割邊的程序
Code數據
#include<cstdio> #include<algorithm>
using namespace std; const int maxn=10005; const int maxm=100005; int n,m,id,cnt,ecnt,Q,info[maxn],nx[maxm<<1],v[maxm<<1]; int dfn[maxn],low[maxn],ori[maxn],scc[maxn]; int find(int x){return !ori[x]?x:ori[x]=find(ori[x]);} void add(int u1,int v1){nx[++ecnt]=info[u1];info[u1]=ecnt;v[ecnt]=v1;} void dfs(int x,int f) { low[x]=dfn[x]=++id; for(int e=info[x];e;e=nx[e]) if(!dfn[v[e]]) { dfs(v[e],x),low[x]=min(low[x],low[v[e]]); if(low[v[e]]>dfn[x]) { int s1=find(v[e]),s2=find(x); if(s1!=s2)ori[s1]=s2; } } else if(v[e]!=f)low[x]=min(low[x],dfn[v[e]]); } int main() { scanf("%d%d%d",&n,&m,&Q); for(int i=1,u1,v1;i<=m;i++)scanf("%d%d",&u1,&v1),add(u1,v1),add(v1,u1); for(int i=1;i<=n;i++)if(!dfn[i])dfs(i,0); for(int i=1,x,y;i<=Q;i++) { scanf("%d%d",&x,&y); if(find(x)==find(y))puts("Y"); else puts("N"); }