思考過程
這個數據範圍好大啊,我想省點空間於是就想到了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;
}