UVALive 5796 Hedge Mazes(双连通+并查集)

来源:互联网 发布:linux ntp时间对时 编辑:程序博客网 时间:2024/06/11 15:49

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=25632

题意:给一个图,有R个点C条边,会进行Q次询问。每次询问两个点u,v之间是否只有一条通路。

题解:两点只有一天通路肯东是在桥上,我们跑双连通分量找桥,用并查集记录,询问是只需判断两点是否属于同一块就行。

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <string>#include <map>#include <cstdlib>#include <cmath>#include <vector>#include <set>#include <queue>const int MAXN = 10010;const int MAXM = 200010;struct Edge {    int to,next;    bool cut;} edge[MAXM];int n,m,q;int head[MAXN],tot;int Low[MAXN],DFN[MAXN],Stack[MAXN];int Index,top;bool Instack[MAXN];bool cut[MAXN];int add_block[MAXN];int bridge;int f[MAXN];int find_father(int u) {    if(f[u]==u)        return u;    return f[u]=find_father(f[u]);}void link(int u,int v) {    int x=find_father(u);    int y=find_father(v);    if(x==y)        return ;    f[x]=y;}void addedge(int u,int v) {    edge[tot].to = v;    edge[tot].next = head[u];    edge[tot].cut = false;    head[u] = tot++;}void Tarjan(int u,int pre) {    int v;    Low[u] = DFN[u] = ++Index;    Stack[top++] = u;    Instack[u] = true;    int son = 0;    for(int i = head[u]; i != -1; i = edge[i].next) {        v = edge[i].to;        if(v == pre)continue;        if( !DFN[v] ) {            son++;            Tarjan(v,u);            if(Low[u] > Low[v])Low[u] = Low[v];            if(Low[v] > DFN[u]) {                bridge++;                edge[i].cut = true;                edge[i^1].cut = true;                link(u,v);///桥            }            if(u != pre && Low[v] >= DFN[u]) {                cut[u] = true;                add_block[u]++;            }        } else if( Low[u] > DFN[v])            Low[u] = DFN[v];    }    if(u == pre && son > 1)cut[u] = true;    if(u == pre)add_block[u] = son - 1;    Instack[u] = false;    top--;}void solve(int N) {    memset(DFN,0,sizeof(DFN));    memset(Instack,false,sizeof(Instack));    memset(add_block,0,sizeof(add_block));    memset(cut,false,sizeof(cut));    Index = top = 0;    bridge = 0;    for(int i = 1; i <= N; i++)        if( !DFN[i] )            Tarjan(i,i);}void init() {    tot = 0;    memset(head,-1,sizeof(head));    for(int i=1; i<=n; i++)        f[i]=i;}int main() {#ifdef ONLINE_JUDGE#else    freopen("in.txt","r",stdin);#endif    while(~scanf("%d%d%d",&n,&m,&q)) {        if(n==0)            break;        init();        int u,v;        for(int i=0; i<m; i++) {            scanf("%d%d",&u,&v);            addedge(u,v);            addedge(v,u);        }        solve(n);        for(int i=0; i<q; i++) {            scanf("%d%d",&u,&v);            printf("%s\n",find_father(u)==find_father(v)?"Y":"N");        }        puts("-");    }    return 0;}


0 0
原创粉丝点击