基准时间限制:1 秒 空间限制:131072 KB 分值: 40
难度:4级算法题
给出一个无向图G的顶点V和边E。进行Q次查询,查询从G的某个顶点V[s]到另一个顶点V[t],是否存在2条不相交的路径。(两条路径不经过相同的边)
(注,无向图中不存在重边,也就是说确定起点和终点,他们之间最多只有1条路)
Input
第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,中间用空格分隔,表示查询的起点和终点。
Output
共Q行,如果从s到t存在2条不相交的路径则输出Yes,否则输出No。
Input示例
4 4 1 2 2 3 1 3 1 4 5 1 2 2 3 3 1 2 4 1 4
Output示例
Yes Yes Yes No No
思路:边双连通分量。
Code:
#include <bits/stdc++.h> using namespace std; const int AX = 1e5+6; int head[AX] , DFN[AX] , LOW[AX] , cutEdge[AX]; map<int,int>mp; int n , m ; int index , tot; struct Node{ int u,v; int next1; }G[AX]; int id; void init( ){ tot = 0 ; id = 0; memset( head , -1 , sizeof(head)); } void add( int u , int v ){ G[tot].u = u ; G[tot].v = v; G[tot].next1 = head[u]; head[u] = tot ++; G[tot].u = v; G[tot].v = u; G[tot].next1 = head[v]; head[v] = tot++; } void tarjan( int x , int fa ){ LOW[x] = DFN[x] = ++index; for( int i = head[x] ; ~i ; i = G[i].next1 ){ if( !DFN[G[i].v] ){ tarjan( G[i].v , x ); LOW[x] = min( LOW[x] , LOW[G[i].v] ); if( LOW[G[i].v] > DFN[x] ){ cutEdge[i] = cutEdge[i^1] = 1; } }else if( G[i].v != fa ){ LOW[x] = min( LOW[x] , DFN[G[i].v] ); } } } void Find_CutEage(){ index = 0 ; memset( LOW , 0 , sizeof(LOW)); memset( DFN , 0 , sizeof(DFN)); memset( cutEdge , 0 , sizeof(cutEdge)); for( int i = 1 ; i <= n ; i++ ){ if( !DFN[i] ){ tarjan( i , -1 ); } } } void dfs( int x ){ DFN[x] = 1; for( int i = head[x] ; ~i ; i = G[i].next1 ){ if( !cutEdge[i] ){ cutEdge[i] = cutEdge[i^1] = 1; mp[x] = mp[G[i].v] = id; if( !DFN[G[i].v] ) dfs(G[i].v); } } } void BccEdge(){ memset(DFN, 0 , sizeof(DFN)); for( int i = 1; i <= n ; i ++ ){ if( !DFN[i] ){ id ++ ; dfs(i); } } } int main(){ cin >> n >> m ; int x , y; init(); for( int i = 0 ; i < m ; i ++ ){ cin >> x >> y; add(x ,y); } Find_CutEage(); BccEdge(); int q; cin >> q; while(q--){ cin >> x >> y; if( mp[x] && mp[y] && mp[x] == mp[y]){ printf("Yes\n"); }else{ printf("No\n"); } } return 0 ; }

本文介绍了一种用于寻找无向图中不相交路径的算法——边双连通分量算法。通过该算法可以判断两个顶点间是否存在两条不相交的路径。文章详细解释了算法的实现步骤,并提供了完整的C++代码示例。
427

被折叠的 条评论
为什么被折叠?



