/* 对于这个问题我不想说什么,感觉ACM太神奇在这里检讨以下,好久没有写并查集都很生疏了 话说学的多也不能忘的快。。。在最短路的DIY中总感觉要用Dijsktra http://hi.baidu.com/yzy%D1%EE%D7%D3%D1%DC/blog/item/829095fd6c14b58eb901a0a3.html find the most comfortable road http://acm.hdu.edu.cn/showproblem.php?pid=1598 题目大意:从一个地方到另外一个地方所经过的路的最大速度和最小速度的差值。这题太好了。 刚开始总以为是最短路问题,用个Floyd应该可以做出来,用两个矩阵,分别记录最大值和最小值,不过很难弄,结果也只有WA,感到很莫名奇妙。 对于题目中的路,按速度进行排序,这样,如果从第 i 条路到第 j 条路之间的所有路能够让 i 和 j 连通,那么,这就存在一条路,且这条路的舒适度就是 两者的差值。 这样,只要枚举从每一条路开始,向前找到可以使得 起点和终点连通的路的舒适度,就可以找到答案了 */ #include <iostream> #include <queue> #include <cstdio> #include <algorithm> using namespace std; const int INF = 0x3fffffff; const int N = 2010; struct node { int x; int y; int dis; friend bool operator <(node a, node b) { return a.dis < b.dis; } }df[N]; int st[N]; int cost[N]; bool hash[N]; int find(int a) {//这里可以状态压缩,可是具体怎样不会。 int r = a; while(st[r] != r) r = st[r]; //st[a] = r; return r; } void merge(int a, int b) { if(a > b) st[b] = a; else st[a] = b; } int main() { int n, m; while(scanf("%d %d", &n, &m) != EOF) { for(int i = 0; i < m; i++) { scanf("%d %d %d", &df[i].x, &df[i].y, &df[i].dis); } sort(df, df + m); // for(int i = 0; i < m; i++) // printf("%d ", df[i].dis); /* for(int i = 0; i < m; i++) { int a = find(df[i].x); int b = find(df[i].y); if( a != b) merge(a, b); } */ int q; scanf("%d", &q); int start, end; while(q--) { scanf("%d %d", &start, &end); int min = INF; int j; for(int i = m - 1; i >= 0; i--) { for(j = 0; j <= n; j++) st[j] = j; j = i; while(j >= 0) { int a = find(df[j].x); int b = find(df[j].y); if( a != b) merge(a, b); if(find(start) == find(end)) break; j--; } if(j < 0) break; if(min > df[i].dis - df[j].dis) min = df[i].dis - df[j].dis; } if(min == INF) min = -1; printf("%d/n", min); } } }