思考过程
这个数据范围好大啊,我想省点空间于是就想到了vector,思路很简单,就是先根据建造时间排个序,然后从小到大的顺序合并,合并一次检查一次,如果最后祖先都一样那么就是通了。
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
int fa[100010];
int n,m;
struct node
{
int x,y,z;
};
vector<node> v;
vector<node>::iterator it;
bool cmp(const node &a,const node &b){return a.z < b.z;}
int find(int pos)
{
if(fa[pos] == pos) return pos;
return fa[pos] = find(fa[pos]);
}
bool search()
{
int pre = fa[1];
register int i;
for(i=1;i<=n;i++)
{
if(fa[i] != pre)
{
return 0;
}
}
return 1;
}
int main()
{
register int i;
//freopen("1.in", "r", stdin);
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)fa[i] = i;
for(i=1;i<=m;i++)
{
int aa,bb,cc;
scanf("%d%d%d",&aa,&bb,&cc);
v.push_back(node {aa,bb,cc});
}
sort(v.begin(),v.end(),cmp);
int ans = 0;
for(it=v.begin();it!=v.end();it++)
{
int aa,bb,cc;
aa = it->x;
bb = it->y;
cc = it->z;
int x = find(aa);
int y = find(bb);
if(x != y)
{
ans = cc;
//printf("add : %d\n",cc);
fa[bb] = aa;
}
if(search())
{
printf("%d",ans);
return 0;
}
//printf("%d\n",cc);
//printf("%d %d %d\n",*(it));
}
printf("-1");
return 0;
}
结果:
这组数据其实在第四次的时候就已经通了,但是我的fa记录有问题,我以为让村子号小的放在前面就可以解决问题。但又发现
最终思路
用个鸡儿的STL,寻常并查集即可,每次联通一条路的时候就n–
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct hh
{
int x,y,t;
}a[200000];
int f[200000],n,m;
int cmp(const hh &a,const hh &b){return a.t<b.t;}
int find(int x){return f[x]==x?x:(f[x]=find(f[x]));}//极致压缩
int main()
{
1s41canf("%d%d",&n,&m);
for(int i=1;i<=m;i++)scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].t);
sort(a+1,a+m+1,cmp);
for(int i=1;i<=n;i++)f[i]=i;
for(int i=1;i<=m;i++)
{
int fx=find(a[i].x),fy=find(a[i].y);
if(fx!=fy)f[fx]=fy,n--;
if(n==1){cout<<a[i].t;return 0;}
}
cout<<-1<<endl;
return 0;
}