题目链接: find the most comfortable road
思路
一开始完全想不到并查集上面,后来看这种方法很巧妙。我们先把所有的边按权值从小到大排列,然后我们枚举每条边,以这条边为起边,再枚举这条边后边的权值比它大的边(同时要合并这条边联结的两个点),直到枚举到了一条边之后,起点和终点联通了,说明这两条边可以联通这条路,就可以用后面的权值大的边-权值小的边了。
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int inf = 0x3f3f3f3f;
struct node{
int from,to,w;
}Edge[2001];
int f[2001],n;
int finder(int x)
{
if(x != f[x])
f[x] = finder(f[x]);
return f[x];
}
int cmp(node a,node b)
{
return a.w < b.w;
}
int combine(int a,int b)
{
int fa = finder(a);
int fb = finder(b);
if(fa != fb)
f[fa] = fb;
}
void init()
{
for(int i = 1; i <= n ; ++i)
f[i] = i;
}
int main()
{
int m,Q,st,ed;
while(cin >> n >> m)
{
for(int i = 1; i <= m; ++i)
{
cin >> Edge[i].from >> Edge[i].to >> Edge[i].w;
}
sort(Edge + 1, Edge + m + 1,cmp);
cin >> Q;
for(int i = 1; i <= Q; ++i)
{
cin >> st >> ed;
int miner = inf;
for(int j = 1; j <= m ;++j )
{
init();
for(int k = j; k <= m; ++k)
{
combine(Edge[k].from,Edge[k].to);
if(finder(st) == finder(ed))
{
miner = min(miner,Edge[k].w - Edge[j].w);
break;
}
}
}
if(miner != inf)
cout << miner << endl;
else
cout << "-1" << endl;
}
}
}