HDU 1272 (并查集)

    xiaoxiao2022-06-29  35

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

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

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

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

    有两种方式 1. 递归

    #include<cstdio> #define Max 100004 int 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; }
    转载请注明原文地址: https://ju.6miu.com/read-1124848.html

    最新回复(0)