// 先对边排序然后贪心、用并查集建最小生成树、然后判断1和N是否连通
#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
#define N 10001
struct E{ // 边结构体
int a,b; // 两个结点编号
int cost; // 边权值
bool operator < (const E &A) const{
return cost<A.cost;
}
}edge[100001];
int Tree[N];
int findRoot(int x){ // 非递归型并查集
int r=x;
while(r!=Tree[r]) r=Tree[r];
int b=x;
int f;
while(b!=r){
f=Tree[b]; Tree[b]=r; b=f; // 遍历过程中将这些结点的双亲结点都设置为已经查找得到的根结点编号
}
return r;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
for(int i=1;i<=n;i++) Tree[i]=i;
for(int i=0;i<m;i++) scanf("%d%d%d",&edge[i].a,&edge[i].b,&edge[i].cost);
sort(edge,edge+m); // 对边进行从小到大排序
int max=0,flag=0; // 最终的答案,最小生成树的最大权值
for(int i=0;i<m;i++){
int a=findRoot(edge[i].a);
int b=findRoot(edge[i].b);
if(a!=b) Tree[a]=b;
if(findRoot(1)==findRoot(n)){
max=edge[i].cost;flag=1;break;
}
}
if(flag==0) printf("-1\n");
else printf("%d\n",max);
}
return 0;
}
#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
#define N 10001
struct E{ // 边结构体
int a,b; // 两个结点编号
int cost; // 边权值
bool operator < (const E &A) const{
return cost<A.cost;
}
}edge[100001];
int Tree[N];
int findRoot(int x){ // 非递归型并查集
int r=x;
while(r!=Tree[r]) r=Tree[r];
int b=x;
int f;
while(b!=r){
f=Tree[b]; Tree[b]=r; b=f; // 遍历过程中将这些结点的双亲结点都设置为已经查找得到的根结点编号
}
return r;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
for(int i=1;i<=n;i++) Tree[i]=i;
for(int i=0;i<m;i++) scanf("%d%d%d",&edge[i].a,&edge[i].b,&edge[i].cost);
sort(edge,edge+m); // 对边进行从小到大排序
int max=0,flag=0; // 最终的答案,最小生成树的最大权值
for(int i=0;i<m;i++){
int a=findRoot(edge[i].a);
int b=findRoot(edge[i].b);
if(a!=b) Tree[a]=b;
if(findRoot(1)==findRoot(n)){
max=edge[i].cost;flag=1;break;
}
}
if(flag==0) printf("-1\n");
else printf("%d\n",max);
}
return 0;
}