给出一个无向图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
边连通分量 一个边连通分量中的任意两点一定有两条边不重合的路径
1 #include <cstdio> 2 #include <cctype> 3 4 const int MAXN=50010; 5 6 int n,m,q,top,inr,sum; 7 8 int dfn[MAXN],low[MAXN],stack[MAXN],belong[MAXN]; 9 10 bool vis[MAXN]; 11 12 struct node { 13 int to; 14 int next; 15 node() {} 16 node(int to,int next):to(to),next(next) {} 17 }; 18 node Edge[MAXN<<1]; 19 20 int head[MAXN],tot=1; 21 22 inline void read(int&x) { 23 int f=1;register char c=getchar(); 24 for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar()); 25 for(;isdigit(c);x=x*10+c-48,c=getchar()); 26 x=x*f; 27 } 28 29 inline void add(int x,int y) { 30 Edge[++tot]=node(y,head[x]); 31 head[x]=tot; 32 Edge[++tot]=node(x,head[y]); 33 head[y]=tot; 34 } 35 36 inline int min(int a,int b) {return a<b?a:b;} 37 38 void tarjan(int u,int fa) { 39 dfn[u]=low[u]=++inr; 40 stack[++top]=u; 41 vis[u]=true; 42 for(int i=head[u];i;i=Edge[i].next) { 43 int v=Edge[i].to; 44 if(v==fa) continue; 45 if(!dfn[v]) { 46 tarjan(v,u); 47 low[u]=min(low[u],low[v]); 48 } 49 else if(vis[v]) low[u]=min(low[u],low[v]); 50 } 51 if(dfn[u]==low[u]) { 52 int t; 53 ++sum; 54 do { 55 t=stack[top--]; 56 belong[t]=sum; 57 vis[t]=false; 58 }while(u!=t); 59 } 60 } 61 62 int hh() { 63 read(n);read(m); 64 for(int x,y,i=1;i<=m;++i) { 65 read(x);read(y); 66 add(x,y); 67 } 68 for(int i=1;i<=n;++i) 69 if(!dfn[i]) tarjan(i,-1); 70 read(q); 71 for(int x,y,i=1;i<=q;++i) { 72 read(x);read(y); 73 if(belong[x]==belong[y]) printf("Yes "); 74 else printf("No "); 75 } 76 return 0; 77 } 78 79 int sb=hh(); 80 int main(int argc,char**argv) {;}