UVALive 5796 Hedge Mazes 解题报告

比赛总结

题目

题意:

一个无向图,每次查询两个点s和t,判断是否s到t间存在且只存在一条简单路径。

题解:

若只存在一条简单路径,那么删掉路径上任意一条边,s和t 都变得不可达,也就是说路径上的边都是桥边。那么如果删掉所有非桥边,符合条件的点对就必须在同一个连通分量里。



//Time:126ms
//Memory:1775B
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
const int MAXN = 200010;
using namespace std;
bool ty[MAXN];
int he[MAXN],to[MAXN],nex[MAXN],top,bel[MAXN],now,btop;
int dfn[MAXN],low[MAXN];
void add(int u,int v)
{
    to[top]=v;
    nex[top]=he[u];
    he[u]=top++;
}
void tarjan(int h,int pre)
{
    dfn[h]=low[h]=++now;
    for(int i=he[h];i!=-1;i=nex[i])
        if((i^1)!=pre)
        {
            if(!dfn[to[i]])
            {
                tarjan(to[i],i);
                low[h]=min(low[to[i]],low[h]);
                if(dfn[h]<low[to[i]])   ty[i]=ty[i^1]=1;
            }
            else    low[h]=min(low[h],dfn[to[i]]);
        }
}
void bfs(int h)
{
    queue<int> que;
    que.push(h);
    ++btop;
    bel[h]=btop;
    while(que.size())
    {
        h=que.front();
        que.pop();
        for(int i=he[h];i!=-1;i=nex[i])
            if(ty[i]&&!bel[to[i]])
                bel[to[i]]=btop,que.push(to[i]);
    }
}
int main()
{
    //freopen("/home/moor/Code/input","r",stdin);
    int n,m,q;
    while(scanf("%d%d%d",&n,&m,&q)&&n&&m&&q)
    {
        int u,v;
        top=0;
        btop=1;
        now=1;
        memset(dfn,0,sizeof(dfn));
        memset(bel,0,sizeof(bel));
        memset(ty,0,sizeof(ty));
        memset(he,-1,sizeof(he));
        for(int i=0;i<m;++i)
        {
            scanf("%d%d",&u,&v);
            add(u,v);
            add(v,u);
        }
        for(int i=1;i<=n;++i)
            if(!dfn[i])
                tarjan(i,-1);
        for(int i=1;i<=n;++i)
            if(!bel[i])
                bfs(i);
        for(int i=0;i<q;++i)
        {
            scanf("%d%d",&u,&v);
            printf("%c\n",bel[u]==bel[v]?'Y':'N');
        }
        printf("-\n");
    }
    return 0;
}



你可能感兴趣的:(UVALive 5796 Hedge Mazes 解题报告)