题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5624
解题思路:
题目中要求每个点都连通,且保证最大边与最小边的差值最小。可以想到的是利用最小生成树的方式解决。每次枚举一条最小边,然后依次寻找比它大的边看是否可以组成一个最小生成树即可。
PS:这题的数据水了。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 2005;
const int maxm = 15005;
const int inf = 0x3f3f3f3f;
struct Edge
{
int u,v,c;
bool operator < (const Edge &rhs) const
{
return c < rhs.c;
}
}edge[maxm];
int n,m,ans,fa[maxn],sum[maxn];
int find(int x)
{
if(fa[x] == x) return x;
return fa[x] = find(fa[x]);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i = 1; i <= m; i++)
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].c);
sort(edge+1,edge+1+m);
ans = inf;
for(int i = 1; i <= m; i++)
{
int maxv = edge[i].c;
int minv = edge[i].c;
for(int j = 1; j <= n; j++) fa[j] = j,sum[j] = 1;
for(int j = i; j <= m; j++)
{
int u = edge[j].u,v = edge[j].v;
int fu = find(u);
int fv = find(v);
if(fu != fv)
{
maxv = edge[j].c;
fa[fv] = fu;
sum[fu] += sum[fv];
}
}
if(sum[find(n)] == n) ans = min(ans,maxv - minv);
}
if(ans == inf) printf("-1\n");
else printf("%d\n",ans);
}
return 0;
}