思路
- 虽然题目看起来稍微有点复杂(比大模拟题好多了www),但其实就是非常简单的最小生成树,因为kruskal记的比较清楚且空间复杂度稍微低一点就用这个了。
- 注意在找到父亲结点的时候,也需要修改查找父节点一路上的点的father值,之后查找就会减少递归次数,不考虑这点的话只能拿到70分(超时)
代码
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long LL;
int father[50005];
struct edge{
int first;
int second;
LL len;
};
bool cmp(edge e1,edge e2){
return e1.len<e2.len;
}
int findfa(int x){
if(father[x]!=x)
father[x]=findfa(father[x]);
return father[x];
}
void setunion(int x,int y){
int yfa=findfa(y);
father[yfa]=findfa(x);
}
int main(){
ios::sync_with_stdio(false);
int n=0,m=0,root=0;
cin>>n>>m>>root;
vector<edge> save;
int init=0;
while(init<n){
father[init]=init;
init++;
}
while(m--){
int v=0,u=0;
LL t=0;
cin>>v>>u>>t;
if(v>u){
int temp=u;
u=v;
v=temp;
}
edge nowe;
nowe.first=v;
nowe.second=u;
nowe.len=t;
save.push_back(nowe);
}
sort(save.begin(),save.end(),cmp);
int count=0;
LL max=0;
for(int i=0;i<save.size();i++){
if(findfa(save[i].first)!=findfa(save[i].second)){
setunion(save[i].first,save[i].second);
max=save[i].len;
count++;
if(count==n-1)
break;
}
}
cout<<max<<endl;
return 0;
}