题目描述
某国有 N N N个村子, M M M条道路,为了实现“村村通工程”现在要”油漆” N − 1 N-1 N−1条道路,因为“和谐”是此国最大的目标和追求,以致于对于最小造价什么的都不在乎了,只希望你所选出来的最长边与最短边的差越小越好。
题目解析
先将边权从大到小排序,枚举边,对于排序后的第 i i i条边,令它为连通 N N N个村子后的最大的一条边。然后使最短的边尽可能大,即从排序后第 i + 1 i+1 i+1条边往下找,直到连通 N N N个村子,取最小值即可。对于 N N N个村子是否已经连通,可以用并查集来维护。
代码
#include<bits/stdc++.h>
using namespace std;
int T,n,m,ans;
int fa[105];
struct A
{
int x,y,w;
}e[10005];
bool cmp(A a,A b) {return a.w>b.w;}
int find(int x) {return fa[x]==x?x:fa[x]=find(fa[x]);}
int main()
{
scanf("%d",&T);
while(T--)
{
ans=1e9;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);
sort(e+1,e+1+m,cmp);
for(int i=1,t;i<=m;i++)
{
for(int j=1;j<=n;j++) fa[j]=j;
t=0;
for(int j=i,x,y;j<=m;j++)
{
x=find(e[j].x);y=find(e[j].y);
if(x!=y)
{
fa[y]=x;t++;
if(t==n-1)
{
ans=min(ans,e[i].w-e[j].w);
break;
}
}
}
}
if(ans!=1e9) cout<<ans<<endl;
else cout<<-1<<endl;
}
}