HDU 1272 (并查集)

来源:互联网 发布:云系统卡盟源码 编辑:程序博客网 时间:2024/05/17 23:35

这道题要求的是每两个点能到达只有一条路。

思考
1. 怎么判断任意两点可以到达?
2. 怎么判断任意两点只有一条路?

解决方法:
1. 如果所有路连通,那么所有路只有一个父亲。
2. 任意两点在最开始的时候是不同根,在当前它们有在搜索属于哪个根的时候,如果根相同那么有环。说明从这两个点出发有
两种方式到达其它同根的点。

注意:
1. 由于不知道有几个节点,要用visit记录。
2. 可能出现0 0 的情况,不过也是满足题意。

有两种方式
1. 递归

#include<cstdio>#define Max 100004int root[Max];int visit[Max];int union_find(int x){    //return x == root[x] ? x : (root[x] = union_find(root[x]));    int _x = x,temp;    while(root[_x] != _x)        _x = root[_x];    while(root[x] != x){        temp = root[x];        root[x] = _x;        x = temp;    }    return _x;}int main(){ //   freopen("in.txt","r",stdin);    int u,v;    while(scanf("%d%d",&u,&v) != EOF && u != -1 && v != -1){        if(u == 0 && v == 0){            printf("Yes\n");            continue;        }        for(int i = 1;i < Max; i++){            root[i] = i;            visit[i] = false;        }        root[u] = v;        visit[u] = true;        visit[v] = true;        int flag = false;        while(scanf("%d%d",&u,&v) != EOF && u && v){            int _u = union_find(u);            int _v = union_find(v);            visit[u] = true;            visit[v] = true;            if(_u == _v)                flag = true;            else {                root[_u] = _v;            }        }        int r = 0;        for(int i = 1;i < Max; i++){            if(visit[i] && root[i] == i)                r++;        }        if(flag == 0 && r == 1)            printf("Yes\n");        else            printf("No\n");    }    return 0;}
0 0