51nod 1076 2条不相交的路径(tarjan)

来源:互联网 发布:淘宝鉴权失败什么意思 编辑:程序博客网 时间:2024/05/22 05:17

题目链接


给出一个无向图G的顶点V和边E。进行Q次查询,查询从G的某个顶点V[s]到另一个顶点V[t],是否存在2条不相交的路径。(两条路径不经过相同的边)

(注,无向图中不存在重边,也就是说确定起点和终点,他们之间最多只有1条路)


学习tarjan算法

十分详细:https://www.byvoid.com/blog/scc-tarjan/

                 http://www.cnblogs.com/fripside/p/3587782.html


主要学习难点:理解low[]数组。

好算法。


AC代码:


#include<iostream>#include<stdio.h>#include<algorithm>#include<vector>#include<cstring>using namespace std;const int maxn=5e4+10;int Stack[maxn];  //每遍历一个点便入栈int top;bool inStack[maxn]; //判断某个点是否已经在栈里面int dfn[maxn],low[maxn];//这两个数组最为关键//dfn(u)为节点u搜索的次序编号(时间戳),//Low(u)为u或u的子树能够追溯到的最早的栈中节点的次序号int beLong[maxn];//判断哪些点联通int Bcnt, Dindex; //记录强连通的个数和当前时间vector<int> v[maxn]; //邻接表保存边int n,m,q;void Init(){    Bcnt=Dindex=top=0;    memset(dfn,-1,sizeof(dfn));    memset(inStack,false,sizeof(inStack));    for(int i=0;i<maxn;i++) v[i].clear();}void tarjan(int u,int fa){    dfn[u]=low[u]=++Dindex;    Stack[++top]=u;    inStack[u]=true;    int u_size=v[u].size();    for(int i=0;i<u_size;i++)    {        int k=v[u][i];        if(dfn[k]==-1)        {//没有访问过            tarjan(k,u);            low[u]=min(low[u],low[k]);        }        else if(inStack[k]&&k!=fa)            low[u]=min(low[u],dfn[k]);    }    if(dfn[u]==low[u])    {           Bcnt++;           int tmp;           do            {                tmp=Stack[top--];                beLong[tmp]=Bcnt;               // printf("bcnt = %d v = %d\n", Bcnt, tmp);                inStack[tmp]=false;            }while(tmp!=u);           // printf("\n");    }}void Solve(){    for(int i=1;i<=n;i++)        if(dfn[i]==-1)           tarjan(i,-1);}int main(){    Init();    scanf("%d%d",&n,&m);    for(int i=0;i<m;i++)    {        int a,b;        scanf("%d%d",&a,&b);        v[a].push_back(b);        v[b].push_back(a);    }   // system("pause");    Solve();   //system("pause");    scanf("%d",&q);    while(q--)    {        int x,y;        scanf("%d%d",&x,&y);        if(beLong[x]==beLong[y])            printf("Yes\n");        else            printf("No\n");    }    return 0;}



1 0
原创粉丝点击