洛谷P1111
题目大概意思是有n个点,m次询问,每次询问连通两个点和当前时间,问在最早什么时候能够把n个点全连通。
全连通即在同一个集合中,我们可以用剩余连通块的数量去判断,也可以用当前最大集合中元素个数去判断。
剩余连通块方法:对于一次查询,如果集合可合并,那么连通块的数量减少一个,直到减为1,此时即全联通。
元素个数:如果当前最大集合中的元素个数等于n,那么说明已经全联通。
除了判断是否全联通,其他的就是并查集的模板了。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
const double EPS=1e-6;
typedef long long ll;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
struct node
{
int x,y,t;
}a[N];
int fa[N];
int finds(int x)
{
if(fa[x]==x)
return x;
return fa[x]=finds(fa[x]);
}
void unions(int x,int y)
{
fa[finds(x)]=finds(y);
}
bool cmp(node a,node b)
{
return a.t<b.t;
}
int main()
{
IOS;
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
fa[i]=i;
for(int i=1;i<=m;i++)
{
cin>>a[i].x>>a[i].y>>a[i].t;
}
sort(a+1,a+m+1,cmp);
int sum=0;
for(int i=1;i<=m;i++)
{
if(finds(a[i].x)!=finds(a[i].y))
{
unions(a[i].x,a[i].y);
n--;
if(n==1)
{cout<<a[i].t<<endl;
return 0;
}
}
}
cout<<"-1"<<endl;
}