题意:
(中文)
思路:
由于只需要知道起点和重点之间的通路里面的最高和最低速度就可以了,那么我们按照速度从小到大利用并查集合并这条边连接的两个点为一个集合,通过并查集来判断要找的起点和重点是否连通了,如果连通就用当前的这条边速度减去添加的第一条边的速度,这个差就是此种方式的最大最小速度之差(因为是按照速度从小到大来添加的,那么当前的速度肯定是通路里面最大的)。遍历所有的情况就能找出最优的值。
Code:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<bitset>
#include<queue>
#include<stack>
#include<list>
#include<map>
#include<set>
#define TEST
#define LL long long
#define Mt(f, x) memset(f, x, sizeof(f));
#define rep(i, s, e) for(int i = (s); i <= (e); ++i)
#ifdef TEST
#define See(a) cout << #a << " = " << a << endl;
#define See2(a, b) cout << #a << " = " << a << ' ' << #b << " = " << b << endl;
#define debug(a, s, e) rep(_i, s, e) {cout << a[_i] << ' ';} cout << endl;
#define debug2(a, s, e, ss, ee) rep(i_, s, e) {debug(a[i_], ss, ee)}
#else
#define See(a)
#define See2(a, b)
#define debug(a, s, e)
#define debug2(a, s, e, ss, ee)
#endif // TEST
const int MAX = 2e9;
const int MIN = -2e9;
const double eps = 1e-8;
const double PI = acos(-1.0);
using namespace std;
const int N = 200 + 5;
struct Node
{
int st;
int to;
int s;
}e[N];
int uf[N];
bool cmp(Node a, Node b)
{
return a.s < b.s;
}
int fd(int n)
{
if(uf[n] != n)
uf[n] = fd(uf[n]);
return uf[n];
}
void init(int n)
{
for(int i = 1; i <= n; ++i)
{
uf[i] = i;
}
}
void unionSet(int a, int b)
{
int fa = fd(a), fb = fd(b);
if(fa != fb)
uf[fa] = fb;
}
int main()
{
int n, m;
while(~scanf("%d%d", &n, &m))
{
for(int i = 0; i < m; ++i)
{
scanf("%d%d%d", &e[i].st, &e[i].to, &e[i].s);
}
sort(e, e + m, cmp);
int q;
scanf("%d", &q);
while(q--)
{
int st, to;
int ans = MAX;
bool hasFind = false;
scanf("%d%d", &st, &to);
for(int i = 0; i < m; ++i)//从第i条边开始添加
{
init(n);
for(int k = i; k < m; ++k)
{
unionSet(e[k].st, e[k]. to);//合并此条边连接的两个点
if(fd(st) == fd(to))
{
ans = min(ans, e[k].s - e[i].s);
hasFind = true;
break;//再向后查找的解都不会优于现在的解
}
}
}
printf("%d\n", hasFind ? ans : -1);
}
}
return 0;
}