问题 1435: [蓝桥杯][历届试题]国王的烦恼

题目链接:https://www.dotcpp.com/oj/problem1435.html

题目描述

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

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

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

下文中的样例说明
第一天后2和3之间的桥不能使用,不影响。
第二天后1和2之间,以及1和3之间的桥不能使用,居民们会抗议。
第三天后3和4之间的桥不能使用,居民们会抗议。
数据规模和约定
对于100%的数据,1< =n< =10000,1< =m< =100000,1< =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

解题思路:

先按道路损坏的时间排个序,题目上说如果两个岛前一天能到达后一天就不能到达,居民就会抗议,我们可以反着来想,最后所有的路都会损坏,所有的岛之间都不能到达。假如从后往前来,根据排序好的数据将小岛合并在一个集合,如果发现两个小岛能够到达了,他们就会抗议一天。使用并查集算法能够轻松解决。

居民会在两个小岛不能到达之后抗议一天,而同一天中可能会有多个小岛不能到达,所以在判断两个小岛是否能到达时还应该判断两个小岛不能到达的时间是不是同一天。

#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
const int N = 10020;
int f[N];
struct date {
	int u, v, t;
}e[N*10];
int cmp(date a, date b) 
{
	return a.t>b.t;
}
int getf(int v) {
	if(f[v]==v)
		return f[v];
	f[v]=getf(f[v]);
	return f[v];
}
int merge(int u, int v){
	int t1, t2;
	t1 = getf(u);
	t2 = getf(v);
	if(t1!=t2) {
		f[t2] = t1;
		return 1;
	} 
	return 0;
}
int main()
{
	int n, m;
	while(scanf("%d%d", &n, &m)!=EOF) 
	{
		for(int i=1; i<=n; i++)
			f[i]=i;
		for(int i=0; i<m; i++)
			scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].t);
		sort(e, e+m, cmp);
		int w = e[0].t+1;
		int ans = 0;
		for(int i=0; i<m; i++) {
			if(merge(e[i].u, e[i].v) && w!=e[i].t) {
				ans++;
				w=e[i].t;
			}
		}
		printf("%d\n", ans);
	}
	return 0;
} 
发布了463 篇原创文章 · 获赞 122 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_41505957/article/details/104212907