1076 2条不相交的路径

                                                                                            1076 2条不相交的路径

 

给出一个无向图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\n");
74         else printf("No\n");
75     }
76     return 0;
77 }
78 
79 int sb=hh();
80 int main(int argc,char**argv) {;}
代码

 

posted @ 2017-09-17 15:11  拿叉插猹哈  阅读(221)  评论(0编辑  收藏  举报