计蒜客-1663-修复公路-MST板子题

某地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车,政府派若干个工程队同时修复这些公路。给出该地区的村庄数 NN,和公路数 MM,公路是双向的。并告诉你每条公路的连着哪两个村庄,什么时候能修完这条公路,问最早什么时候任意两个村庄能够通车。

输入格式
第一行两个正整数 N,M\ (2 \le N \le 100,1\le M \le 10^5)N,M (2≤N≤100,1≤M≤10
5
),分别表示村庄的个数和公路数。

下面 MM 行,每行三个正整数 x, y, t\ (1\le x,y \le n,1\le t \le 10^5)x,y,t (1≤x,y≤n,1≤t≤10
5
),告诉你这条公路连着 x,yx,y 两个村庄,在时间 tt 时能修复完成这条公路。

输出格式
如果全部公路修复完毕仍然存在两个村庄无法通车,则输出 -1−1,否则输出最早什么时候任意两个村庄能够通车。

输出时每行末尾的多余空格,不影响答案正确性

样例输入复制
4 4
1 2 6
1 3 4
1 4 5
4 2 3
样例输出复制
5

本题一看就是MST的板子题,废话不多说,直接上代码,多多复习,孰能生巧。

//@author:hairu,wu
//@from:ahut
#include
#include
#include
#include
using namespace std;

struct edge{
	int a;
	int b;
	int cost;
};

int n,m;//n个村庄,m条道路
int root[10010]; 

bool cmp(edge e1,edge e2){
	return e1.cost<=e2.cost;
}

int findRoot(int x){
	if(root[x]==-1){
		return x;
	}else{
		//进行路径压缩 
		int t=findRoot(root[x]);
		root[x]=t;
		return t;
	}
}

int main(){
	vector<edge> v;//原始边的集合
	vector<edge> k;//结果边的集合
	
	cin >> n>> m;
	for(int i=1;i<=n;i++){
		root[i]=-1;
	}
	for(int i=1;i<=m;i++){
		edge e;
		cin >> e.a>>e.b>>e.cost;
		v.push_back(e);
	}
	//按照边的权值排序
	sort(v.begin(),v.end(),cmp); 
	//遍历每条边
	vector<edge>::iterator ite=v.begin();
	while(ite!=v.end()){
		if(findRoot(ite->a)!=findRoot(ite->b)){
//			cout<a<<"c"<b<
			//不属于同一个集合
			//*****************加入同一个集合 
			int x=findRoot(ite->a);
			int y=findRoot(ite->b);
			root[x]=y;
			//*****************上面三行非常重要, 
			k.push_back(*ite);//将边加入结果集 
			v.erase(ite);//删除这条边 
			//判断是否属于同一个集合 
			if(k.size()==n-1){
				break;
			}
		} else{
			//属于同一个集合 
			ite++;
		}
	} 
	if(k.size()==n-1){
		//所有的点全部加入且边符合N-1 
		int Max=0;
		for(int i=0;i<k.size();i++){
			if(k[i].cost>Max){
				Max=k[i].cost;
			}
		} 
		cout<<Max<<endl;
	}else{
		//不能生成 MST 
		cout<<-1<<endl; 
	}
	return 0;
}

你可能感兴趣的:(MST)