并查集—HDU1272

HDU1272
在这里插入图片描述

用并查集来做,当新插入的通道(a—b)属于同一个集合,说明a—b已经连通,再插入会导致成环
这题有几个注意点:

  • 插入的通道 6 - 8, 并不表明 1~8 都在集合中(集合中可能只有6、8),故在判断时要注意有些数值在集合中,哪些不在

  • 不仅要保证插入通道(a—b)时,a、b不在同一集合,还要保证最后统计所有已插入集合的数,只存在一个集合,如果是多个集合说明有些点之间不可达 下面代码中的:judge函数

  • 输入 0 0 时,返回 true

package 并查集;

import java.util.Scanner;

/**
 * created by Ethan-Walker on 2018/11/8
 */
public class HDU1272 {

    public static int[] parent = new int[100001];

    public static void init(int count) {
        for (int i = 0; i <= count; i++) {
            parent[i] = -1;
        }
    }

    public static boolean union(int a, int b) {
        int set1 = find(a);
        int set2 = find(b);
        if (set1 == set2) {
            return false;
        } else {
            if (parent[set1] > parent[set2]) {
                parent[set2] += parent[set1];
                parent[set1] = set2;
            } else {
                parent[set1] += parent[set2];
                parent[set2] = set1;
            }
            return true;
        }
    }

    /**
     * 注意,要保证最后只能有一个集合
     * @param max
     * @return
     */
    public static boolean judge(int max) {
        // 计算树根的个数,1~max之间 parent[i] = -1 不算,因为未出现在图中
        int count = 0;
        for (int i = 1; i <= max; i++) {
            if (parent[i] < -1) { // <-1 说明添加到集合中 且是根节点, =-1说明没有加到集合中
                count++;
                if (count > 1) return false;
            }
        }
        return true;
    }

    public static int find(int a) {
        while (parent[a] > 0) a = parent[a];
        return a;
    }

    public static void main(String[] args) {
        int a, b;
        Scanner sc = new Scanner(System.in);
        boolean flag = true;
        init(100000);
        int max = 0;
        while (true) {
            a = sc.nextInt();
            max = Math.max(max, a);
            b = sc.nextInt();
            max = Math.max(max, b);
            if (a == -1 && b == -1) return;
            if (a == 0 && b == 0) {
                if (flag && judge(max)) {
                    System.out.println("Yes");
                } else {
                    System.out.println("No");
                }
                init(max);
                max = 0;
                flag = true;
            } else {
                if (flag) { // flag变成 false之后就不必执行了
                    flag = union(a, b);
                }
            }
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值