/*题意:已知一张图,给定起点终点,求出包含起点和终点的生成树:
使得生成树的最大边权与最小边权之差最小,并输出其值。若不连通,输出-1*/
/*
思路:先对边按权值排序。然后从最小的边开始枚举至最大边,然后枚举比当前边大的所有边,
直到出现满足条件的生成树为止,此时更新ans。
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#define N 205
using namespace std;
const int inf = 0x3f3f3f3f;
typedef struct note {
int u; int v; int w;
}edge;
edge e[5 * N];
int f[N];
int n, m;
int cmp(edge a, edge b)
{
return a.w < b.w;
}
void init()
{
for (int k = 1; k <= n; k++)
f[k] = k;
}
int find(int x)
{
return x == f[x] ? x : f[x] = find(f[x]);
}
int merge(int x, int y)
{
int t1, t2;
t1 = find(x); t2 = find(y);
if (t1 != t2)
{
f[t2] = t1;
return 1;
}
return 0;
}
int main()
{
while (scanf("%d%d", &n, &m) != EOF)
{
int ans;
for (int i = 1; i <= m; i++)
scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w);
sort(e + 1, e + m + 1, cmp);
int T;
scanf("%d", &T);
while (T--)
{
int start, endd;
scanf("%d%d", &start, &endd);
ans = inf;
for (int i = 1; i <= m; i++)
{
init();//每次枚举最小边时,都要初始化集合
for (int j = i; j <= m; j++)//从i开始枚举,方便输出仅有一条边(ans为0)的情况
{
merge(e[j].u, e[j].v);
if (find(start) == find(endd))
{
ans = min(ans, e[j].w - e[i].w);
break;//一旦找到符合条件的生成树,此时舒适度一定是当前最小的,直接跳出循环
}
}
}
if (ans == inf) ans = -1;//图不连通
printf("%d\n", ans);
}
}
return 0;
}
hdu1598 求满足最大权值最小权值差最小的生成树
最新推荐文章于 2021-08-27 16:11:47 发布