https://www.51nod.com/Challenge/Problem.html#!#problemId=1076

给出一个无向图G的顶点V和边E。进行Q次查询,查询从G的某个顶点V[s]到另一个顶点V[t],是否存在2条不相交的路径。(两条路径不经过相同的边)
(注,无向图中不存在重边,也就是说确定起点和终点,他们之间最多只有1条路)
输入
第1行:2个数M N,中间用空格分开,M是顶点的数量,N是边的数量。(2 <= M <= 25000, 1 <= N <= 50000)
第2 - N + 1行,每行2个数,中间用空格分隔,分别是N条边的起点和终点的编号。例如2 4表示起点为2,终点为4,由于是无向图,所以从4到2也是可行的路径。
第N + 2行,一个数Q,表示后面将进行Q次查询。(1 <= Q <= 50000)
第N + 3 - N + 2 + Q行,每行2个数s, t,中间用空格分隔,表示查询的起点和终点。
输出
共Q行,如果从s到t存在2条不相交的路径则输出Yes,否则输出No。
输入样例
4 4
1 2
2 3
1 3
1 4
5
1 2
2 3
3 1
2 4
1 4
输出样例
Yes
Yes
Yes
No
No

学习了下tarjan。。。求有向图的强连通分量,求无向图时使回边不能指向父节点即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 25000+10;
const int MAXM = 50000+10;
int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN];
int index,top;
int scc; //强连通分量的个数
bool InStack[MAXN];
int num[MAXN];//各个强连通分量包含点的个数
vector <int> e[MAXM]; //边表
void tarjan(int u,int fa){
int v;
Low[u]=DFN[u]=++index;
Stack[top++]=u;
InStack[u]=true;
int size=e[u].size();
for(int i=0;i<size;i++){
v=e[u][i];
if(v==fa) continue; //
if(!DFN[v]){
tarjan(v,u);
Low[u]=min(Low[u],Low[v]);
}else if(InStack[v]){
Low[u]=min(Low[u],DFN[v]);
}
}
if(Low[u]==DFN[u]){
scc++;
do{
v=Stack[--top];
InStack[v]=false;
Belong[v]=scc; //标记属于哪一个强连通分量
// num[scc]++;
}while(v!=u);
}
}
void solve(int n){
memset(DFN,0,sizeof(DFN));
memset(InStack,false,sizeof(InStack));
memset(num,0,sizeof(num));
index=scc=top=0;
for(int i=1;i<=n;i++)
if(!DFN[i])
tarjan(i,-1);
}
int m,n,q,x,y;
int main(){
freopen("in","r",stdin);
scanf("%d%d",&m,&n);
while(n--){
scanf("%d%d",&x,&y);
e[x].push_back(y);
e[y].push_back(x);
}
solve(m);
scanf("%d",&q);;
while(q--){
scanf("%d%d",&x,&y);
if(Belong[x]==Belong[y]) printf("Yes\n");
else printf("No\n");
}
return 0;
}