并查集-洛谷P1111修复公路

一、算法分析

这道题的算法很直观,对于两个村庄之间的连接性,直接用并查集进行处理就可以。处理时要先将修路时间进行排序,然后按时间顺序将相连的村庄并在同一集合里面。

二、代码贴上

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
using namespace std;
const int maxn=1005;
const int maxm=100005;
int pa[maxn],r[maxn];
int n,m;
struct edge{
	int xx;
	int yy;
	int tim;
	edge(int xp,int yp,int ti):xx(xp),yy(yp),tim(ti){}
};
bool cmp(edge x,edge y){
	return x.tim<y.tim;
}
typedef vector<edge> VE;
VE a;
int findy(int x){
    return pa[x]==x?x:pa[x]=findy(pa[x]);
}
bool pd(int x,int y){
	return (findy(x)==findy(y));
}
void uni(int x,int y){
	int xx=findy(x);
	int yy=findy(y);
	if(xx!=yy){
		if(r[xx]>r[yy]) swap(xx,yy);
		else if(r[xx]==r[yy]) r[xx]++;
		pa[xx]=yy;
		r[yy]+=r[xx];
	}
}
bool finished(){
	int p=findy(1);
	for(int i=1;i<=n;i++){
		if(findy(i)!=p) return false;
	}
	return true;
}
int main(){
	
	cin>>n>>m;
	int x,y,t;
	int failed=1;
	pa[1]=1;
	for(int i=1;i<=n;i++) pa[i]=i;
	for(int i=0;i<m;i++){
		cin>>x>>y>>t;
		a.push_back(edge(x,y,t));
	}
	sort(a.begin(),a.end(),cmp);
	for(int i=0;i<m;i++){
		uni(a[i].xx,a[i].yy);
		if(finished()){
			cout<<a[i].tim;
			failed=0;
			break;
		}
	}
	if(failed) cout<<-1<<endl;
	return 0;
}

三、作者

Bowen
本文代码及题解均为作者原创,转载请注明出处。
本文作者水平有限,如有纰漏之处,敬请斧正。

发布了50 篇原创文章 · 获赞 7 · 访问量 1140

猜你喜欢

转载自blog.csdn.net/numb_ac/article/details/103392872