tarjan判环(51Nod - 1076)

tarjan判环(51Nod - 1076)

51Nod - 1076
vj链接


模板

int DFN[maxn],low[maxn],cnt=0;
bool vis[maxn],inStack[maxn];///每次使用要清空
vector <int> edge[maxn];
stack <int> st;
void dfs(int u,int pre)///该例为无向图,pre保证没有n为2的环,可初始化为-1
{
    vis[u]=1;
    DFN[u]=low[u]=++cnt;
    st.push(u);
    inStack[u]=1;
    int minn=DFN[u];
    if(edge[u].size()>0)
    {
        for(int i=0;iint v=edge[u][i];
            if(v==pre) continue;
            if(!vis[v])
            {
                dfs(v,u);
            }
            if(inStack[v])
                minn=min(low[v],minn);
        }
    }
    low[u]=minn;
    if(low[u]==DFN[u])
    {
        while(1)
        {
            int x=st.top();
            st.pop();
            inStack[x]=0;
            low[x]=DFN[u];
            if(x==u) break;
        }
    }
}

给出一个无向图G的顶点V和边E。进行Q次查询,查询从G的某个顶点Vs到另一个顶点Vt,是否存在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。

Sample Input

4 4
1 2
2 3
1 3
1 4
5
1 2
2 3
3 1
2 4
1 4

Sample Output

Yes
Yes
Yes
No
No


AC代码

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define LL long long
const int maxn=25000+7;

int DFN[maxn],low[maxn],cnt=0,vis[maxn];
vector <int> edge[maxn];
stack <int> st;
void dfs(int u,int pre)
{
    vis[u]=1;
    DFN[u]=low[u]=++cnt;
    st.push(u);
    int minn=DFN[u];
    if(edge[u].size()>0)
    {
        for(int i=0;iint v=edge[u][i];
            if(v==pre) continue;
            if(!vis[v])
            {
                dfs(v,u);
            }
            minn=min(low[v],minn);
        }
    }
    low[u]=minn;
    if(low[u]==DFN[u])
    {
        while(1)
        {
            int x=st.top();
            st.pop();
            low[x]=DFN[u];
            if(x==u) break;
        }
    }
}
int main()
{
    int n,m,i,j,k,x,y;
    scanf("%d%d",&n,&m);
    for(i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        edge[x].push_back(y);
        edge[y].push_back(x);
    }
    for(i=1;i<=n;i++)
    {
        if(!vis[i]) dfs(i,0);
    }
    int q;
    scanf("%d",&q);
    while(q--)
    {
        scanf("%d%d",&x,&y);
        if(low[x]==low[y]) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

你可能感兴趣的:(ACM)