题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1598
思路:通过思路转换,可以看出是求两个点之间最大边权值与最小边权值之差最小的。克鲁斯卡尔算法枚举之~
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <queue> #include <stack> #include <vector> #include <cstdlib> #include <string> using namespace std; int n,m; int f[210]; struct node { int u,v; int w; }map[1020]; int getf(int a) { if(f[a] == a) return a; f[a] = getf(f[a]); return f[a]; } void merge(int a, int b) { int x = getf(a); int y = getf(b); if(x!=y) f[y] = x; } void init() { for(int i=1; i<=n; i++) { f[i] = i; } } bool cmp(node a, node b) { return a.w < b.w; } int solve(int start, int end) { int maxn = -1; int minn = 999999999; sort(map,map+m,cmp); int res = 999999999; for(int k = 0; k < m; k++) { init(); maxn = -1; minn = 999999999; for(int i = k; i < m; i++) { if(getf(map[i].u) != getf(map[i].v)) { merge(map[i].u, map[i].v); maxn = max(maxn, map[i].w); minn = min(minn, map[i].w); } if(getf(start) == getf(end)) { res = min(maxn - minn, res); break; } } } if(res == 999999999) res = -1; return res; } int main() { int q; while(scanf("%d %d", &n, &m)!=EOF) { for(int i=0; i<m; i++) { scanf("%d %d %d", &map[i].u, &map[i].v, &map[i].w); } scanf("%d", &q); int s[20][2]; for(int i=1; i<=q; i++) { init(); scanf("%d %d", &s[i][0], &s[i][1]); printf("%d\n", solve(s[i][0],s[i][1])); } } return 0; }
时间: 2024-10-13 11:57:12