畅通工程

题目描述:

    省政府畅通工程的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路连通,只要互相间接通过道路可达即可)。问至少还需要建设多少条道路?

输入:

    测试输入包含若干测试用例。每个测试用例的第一行给出两个正整数,分别是城镇数目N(<1000)和道路数目M,随后的M行对应M条道路,每行给出一对正整数,分别是该条道路直接连通的两个城镇的编号。为简单起见,城镇从1到N编号。当N==0时,输入结束,该用例不被处理。

输出:

    对每个测试用例,在1行里输出最少还需要建设的道路数目。

样例输入:

    4 2
    1 3
    4 3
    3 3
    1 2
    1 3
    2 3
    5 2
    1 2
    3 5
    999 0
    0

样例输出:

    1
    0
    2
    998

示例代码:

import java.util.Scanner;

public class Main {
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()){
            int n = scanner.nextInt();
            if (n==0){break;}
            Unionset city = new Unionset(n);
            int m = scanner.nextInt();
            for (int i=0;i<m;i++){
                int firstnode = scanner.nextInt();
                int secondnode = scanner.nextInt();
                city.unionTowns(firstnode,secondnode);
            }
            int sets = city.setsNumber(n,city);
            System.out.println(sets);
        }
    }
}

//并查集类
public class Unionset {
    int size;
    int[] towns;
    int[] weight;
    public Unionset(int size){
        this.size = size;
        towns = new int[size+1];
        weight = new int[size+1];
        for (int i=1;i<=size;i++){
            towns[i]=i;
            weight[i]=1;
        }
    }

    public int findroot(int town_num){
        if (town_num==towns[town_num]){return town_num;}
        else {
            int root_num = findroot(towns[town_num]);
            towns[town_num]=root_num;
            return root_num;
        }
    }

    public void unionTowns(int firstTnmb,int secondTnmb){
        int firstroot = findroot(firstTnmb);
        int secondroot = findroot(secondTnmb);
        if (firstroot==secondroot){return;}
        else {
            int firstweight = weight[firstroot];
            int secondweight = weight[secondroot];
            if (firstweight<=secondweight){towns[firstroot]=secondroot;weight[secondroot]+=firstweight;}
            else {towns[secondroot]=firstroot;weight[firstroot]+=secondweight;}
        }
    }

    public int setsNumber(int size,Unionset city){
        int sets = -1;
        int[] towns = city.towns;
        for (int j=1;j<=size;j++){
            int tmp = towns[j];
            if (tmp==j){sets++;}
        }
        return sets;
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值