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;
}

 

posted @ 2017-03-19 16:58  IIIIIIIIIU  阅读(357)  评论(0编辑  收藏  举报