/**
* 枚举 + kruskal:
* 因为要找的是一条路的最大值减最小值。 就可以利用kruskal的贪心思想。
* 把所有边按权从小到大(从大到小其实都一样)排序。然后一一枚举,找出所有能使得x和y连通的路径。
* 再在这些路径中找一个舒适度最高的,也就得出答案了。
* 对于这题来说,生成树是不定的,也就是说,只要在贪心的过程中,有x和y在同一集合中,
* 立马break,而根据贪心的思想(或者说,因为数组已经排序),
* 只要把此时的内层循环的nodes[k].w - nodes[i].w 就是这条路径的舒适度。
*/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <queue>
#include <map>
#include <vector>
#include <algorithm>
#define DEBUG 0
#define INF 0x7fffffff
#define MAXS 1005
typedef long long LL;
using namespace std;
struct Edge {
int u, v, w;
bool operator < (const Edge &a) const {
return w < a.w;
}
Edge() {}
Edge(int uu, int vv, int ww) {u = uu; v = vv; w = ww;}
}edges[MAXS];
int fa[MAXS];
int get_fa(int x) { return x == fa[x] ? x : fa[x] = get_fa(fa[x]); }
void Union(int x, int y) { fa[get_fa(y)] = get_fa(x);}
int main()
{
int n, m;
while(scanf("%d%d", &n, &m) != EOF) {
for(int i = 0; i < m; i ++)
scanf("%d%d%d", &edges[i].u, &edges[i].v, &edges[i].w);
sort(edges, edges + m);
int curMin;
int x, y, q; scanf("%d", &q);
while(q --) {
scanf("%d%d", &x, &y);
curMin = INF;
for(int i = 0; i < m; i ++) {
/** 初始化父节点,并查集。 */
for(int j = 1; j <= n; j ++) fa[j] = j;
int k;
for(k = i; k < m; k ++) {
Union(edges[k].u, edges[k].v);
if(get_fa(x) == get_fa(y))
break;
}
if(k == m) break;
if(curMin > edges[k].w - edges[i].w)
curMin = edges[k].w - edges[i].w;
}
if(curMin == INF)
printf("-1\n");
else
printf("%d\n", curMin);
}
}
return 0;
}
HDU 1598 find the most comfortable road 枚举 + kruskal算法
最新推荐文章于 2020-04-18 20:46:01 发布