uvalive5796(图论、桥、并查集)

来源:互联网 发布:淘宝图片如何ps 编辑:程序博客网 时间:2024/05/19 06:51

题意:

给出一个无向图,每次询问,问两个点之间是否有一条唯一的不经过重复点的路径。


思路:

如果存在这样的路径,那么路径上的点就都是桥,我们可以找出图中所有的桥,把非桥边删去,把桥连的点塞到并查集中,查询的时候每次只要看两个点是否在同一个并查集即可。

这题比赛的时候没过,赛后也没写,贴一个我们校一队的代码吧。


代码:

#include<iostream>#include<map>#include<vector>#include<string.h>#include<stdio.h>using namespace std;const int maxa = 10005;vector<int> e[maxa];map<int, bool> mp[maxa];bool cut[maxa];int low[maxa], dfn[maxa], vis[maxa];void cut__(int cur, int father, int dep, int n){    vis[cur] = 1;dfn[cur] = low[cur] = dep;    int children = 0;    for(int k = 0;k < e[cur].size(); k++){        int i = e[cur][k];        if(i != father && 1 == vis[i]){            if(dfn[i] < low[cur]){                low[cur] = dfn[i];            }        }        if(0 == vis[i]){            cut__(i , cur, dep+1, n);            children ++;            if(low[i] < low[cur]) low[cur] = low[i];            if((father == -1 && children > 1) || father != -1 && low[i] >= dfn[cur]) cut[cur] = true;            if(low[i] > dfn[cur]){                mp[cur][i] = mp[i][cur] = 1;               // printf("*------%d %d\n", cur, i);            }        }    }    vis[cur] = 2;}int fa[maxa];int find(int ii){    return fa[ii] = fa[ii] == ii? ii:find(fa[ii]);}int main(){    int r, c, q;    while(scanf("%d%d%d", &r, &c, &q), r||c||q){        for(int i = 0;i <= r; i++){            e[i].clear();            mp[i].clear();        }        for(int i = 1;i <= r; i++){            fa[i] = i;        }        memset(cut, 0, sizeof(cut));        memset(vis, 0, sizeof(vis));        memset(low, 0, sizeof(low));        memset(dfn, 0, sizeof(dfn));        for(int i = 0;i < c; i++){            int u, v;            scanf("%d%d", &u, &v);            e[u].push_back(v);            e[v].push_back(u);        }        for(int i = 1; i <= r; i++){            if(vis[i] == 0){                cut__(i, -1, 0, r);            }        }        for(int i = 1; i <= r; i++){            for(int k = 0; k< e[i].size(); k++){                if(mp[i][e[i][k]] == 1){                    fa[find(i)] = find(e[i][k]);                    //printf("%d %d ------\n", i, e[i][k]);                }            }        }        while(q--){            int u, v;            scanf("%d%d", &u, &v);            if(find(u) == find(v)){                puts("Y");            }else{puts("N");            }        }puts("-");    }}


0 0
原创粉丝点击