给你一个有n个点和m条边的无向连通图,每条边都有一个权值w.我们定义,对于一条路径,它的Charm value为该路径上所有边的权值的最大值与最小值的差.
询问从1到n的所有路径的Charm value的最小值.
输入
第一行,有两个整数n,m(1≤n≤200,n−1≤m≤1000),表示该图有n个点和m条边.
接下来m行,每行三个整数u,v,w(1≤u,v≤n,1≤w≤1000000),表示点u和点v之间有一条权值为w的边.
输出
输出一个数,即从1到n的所有路径的Charm value的最小值.
样例输入:
4 4
3 4 1
2 3 2
1 2 4
2 4 3
样例输出
1
题解:
枚举最小的处于生成树上的那条边,做最小生成树,当1与N在同一棵生成树中的时候,用已知生成树中的最大的边来更新答案。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<queue>
#define INF 1999122700
#define LiangJiaJun main
using namespace std;
struct data{
int u,v,w;
}a[5004];
int ans=INF;
inline bool dex(data s, data q){return s.w < q.w;}
int n,m,f[204];
int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
int kruskal(int st){
for(int i=1;i<=n;i++) f[i]=i;
int p=a[st].u,q=a[st].v,maxn=a[st].w;
f[p]=q;
if(find(1) == find(n)) return 0;
for(int i=st+1;i<=m;i++){
int p=find(a[i].u) , q=find(a[i].v);
if(p!=q){
f[p]=q;
maxn=max(maxn,a[i].w);
}
if(find(1)==find(n))return maxn-a[st].w;
}
return INF;
}
int LiangJiaJun(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
sort(a+1,a+m+1,dex);
for(int i=1;i<=m;i++)ans = min(kruskal(i),ans);
cout<<ans<<endl;
return 0;
}