题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1598
find the most comfortable road
Memory Limit: 32768/32768 K (Java/Others)
题解
并查集+贪心。
我们先对所有的边排序,然后对于每个查询,我们枚举开始的边,然后用并查集维护连通性,一旦目前的边足以连通查询的顶点对,那么说明这一轮的答案就出来了,像这样做m轮就能求出答案。最坏情况也就O(m^2)。
代码
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#define X first
#define Y second
#define mp make_pair
using namespace std;
const int maxn = 1e3+10;
const int INF = 0x3f3f3f3f;
int n, m;
int fa[maxn];
int find(int x) { return fa[x] = fa[x] == x ? x : find(fa[x]); }
struct Edge {
int u, v, w;
bool operator < (const Edge& tmp) const {
return w < tmp.w;
}
}egs[maxn];
int main() {
while (scanf("%d%d", &n, &m) == 2 && n) {
for (int i = 0; i < m; i++) {
scanf("%d%d%d", &egs[i].u, &egs[i].v, &egs[i].w);
}
sort(egs, egs + m);
int q;
scanf("%d", &q);
while (q--) {
int s, d;
scanf("%d%d", &s, &d);
int ans = INF;
for (int i = 0; i < m; i++) {
for (int i = 1; i <= n; i++) fa[i] = i;
for (int j = i; j < m; j++) {
Edge& e = egs[j];
int pu = find(e.u);
int pv = find(e.v);
if (pu != pv) {
fa[pv] = pu;
}
if (find(s) == find(d)) {
ans = min(ans, egs[j].w - egs[i].w);
break;
}
}
}
if (ans < INF) printf("%d
", ans);
else puts("-1");
}
}
return 0;
}
Notes
很多枚举区间的问题,排序之类的预处理一下,一般只要枚举上界就可以了。