AC日记——2条不相交的路径 51nod 1076
基准时间限制: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
相关问题
3条不相交的路径
1280
思路;
裸tarjan;
来,上代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define maxn 250050 using namespace std; struct EdgeType { int v,e; }; struct EdgeType edge[maxn<<2]; int n,m,dfn[maxn],low[maxn],tarjan_dfn; int head[maxn],cnt,stack[maxn],top; int bel[maxn],loop; char Cget; inline void in(int &now) { now=0,Cget=getchar(); while(Cget>'9'||Cget<'0') Cget=getchar(); while(Cget>='0'&&Cget<='9') { now=now*10+Cget-'0'; Cget=getchar(); } } void tarjan(int now,int fa) { dfn[now]=++tarjan_dfn,low[now]=dfn[now]; stack[++top]=now; for(int i=head[now];i;i=edge[i].e) { if(fa==edge[i].v) continue; if(!dfn[edge[i].v]) tarjan(edge[i].v,now); low[now]=min(low[now],low[edge[i].v]); } if(low[now]==dfn[now]) { loop++; while(stack[top]!=now) { bel[stack[top]]=loop; top--; } bel[stack[top--]]=loop; } } int main() { in(n),in(m); int u,v; while(m--) { in(u),in(v); edge[++cnt].v=v,edge[cnt].e=head[u],head[u]=cnt; edge[++cnt].v=u,edge[cnt].e=head[v],head[v]=cnt; } for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i,0); in(m); while(m--) { in(u),in(v); if(bel[u]==bel[v]) puts("Yes"); else puts("No"); } return 0; }