国王的烦恼-Java

题目描述:

C国由n个小岛组成,为了方便小岛之间联络,C国在小岛间建立了m座大桥,每座大桥连接两座小岛。
两个小岛间可能存在多座桥连接。然而,由于海水冲刷,有一些大桥面临着不能使用的危险。 

如果两个小岛间的所有大桥都不能使用,则这两座小岛就不能直接到达了。
然而,只要这两座小岛的居民能通过其他的桥或者其他的小岛互相到达,他们就会安然无事。
但是,如果前一天两个小岛之间还有方法可以到达,后一天却不能到达了,居民们就会一起抗议。 

现在C国的国王已经知道了每座桥能使用的天数,超过这个天数就不能使用了。
现在他想知道居民们会有多少天进行抗议。 

下文中的样例说明 
第一天后23之间的桥不能使用,不影响。 
第二天后12之间,以及13之间的桥不能使用,居民们会抗议。 
第三天后34之间的桥不能使用,居民们会抗议。 
数据规模和约定 
对于100%的数据,1< =n< =100001< =m< =1000001< =a,  b< =n,  1< =t< =100000

输入:

输入的第一行包含两个整数n,  m,分别表示小岛的个数和桥的数量。 
接下来m行,每行三个整数a,  b,  t,分别表示该座桥连接a号和b号两个小岛,能使用t天。
小岛的编号从1开始递增。

输出:

输出一个整数,表示居民们会抗议的天数。

样例输入:

4 4
1 2 2
1 3 2
2 3 1
3 4 3

样例输出:

2

参考解答:

import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

class bridge {
    public int island_a;	// 起点的小岛
    public int island_b	;	// 终点的小岛
    public int weight;		// 使用的天数 也就是权重
    public bridge(int island_a, int island_b, int weight) {
        this.island_a = island_a;
        this.island_b = island_b;
        this.weight = weight;
    }
}

public class Main {
	private static int tree[];
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int num_island = sc.nextInt();
        int num_bridges = sc.nextInt();		
        tree = new int[num_island + 1];
        init(num_island);
        bridge[] bridges = new bridge[num_bridges + 1];	
        for (int i = 1; i <= num_bridges; i++) {
        	bridges[i] = new bridge(sc.nextInt(), sc.nextInt(), sc.nextInt());
        }
        Arrays.sort(bridges, 1, num_bridges + 1, new Comparator<bridge>() {
            @Override
            public int compare(bridge bridge_1, bridge bridge_2) {
                return bridge_2.weight - bridge_1.weight;
            }
        });
        int sum_days = 0;
        for (int i = 1, last_day = 0; i <= num_bridges; i++) {
        	boolean not_linked = unite(bridges[i].island_a, bridges[i].island_b);
        	if (not_linked && bridges[i].weight != last_day) {
        		sum_days++;
        		last_day = bridges[i].weight;
        	}
        }
        System.out.println(sum_days);
    }
    
    private static void init(int num_island) {
    	for (int i = 1; i <= num_island; i++) {
    		tree[i] = i;
    	}
    }
    
    private static int find_root(int island) {
    	if (tree[island] == island) {
    		return island;
    	}
    	else {
    		return tree[island] = find_root(tree[island]);
    	}
    }
    
    private static boolean unite(int island_a, int island_b) {
    	int root_a = find_root(island_a);
    	int root_b = find_root(island_b);
    	if (root_a != root_b) {
    		tree[root_a] = root_b;
    		return true;
    	}
    	else {
    		return false;
    	}
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值