Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Submit
Status
Description
XX星有许多城市,城市之间通过一种奇怪的高速公路SARS(Super Air Roam Structure---超级空中漫游结构)进行交流,每条SARS都对行驶在上面的Flycar限制了固定的Speed,同时XX星人对 Flycar的“舒适度”有特殊要求,即乘坐过程中最高速度与最低速度的差越小乘坐越舒服 ,(理解为SARS的限速要求,flycar必须瞬间提速/降速,痛苦呀 ),
但XX星人对时间却没那么多要求。要你找出一条城市间的最舒适的路径。(SARS是双向的)。
Input
输入包括多个测试实例,每个实例包括:
第一行有2个正整数n (1<n<=200)和m (m<=1000),表示有N个城市和M条SARS。
接下来的行是三个正整数StartCity,EndCity,speed,表示从表面上看StartCity到EndCity,限速为speedSARS。speed<=1000000
然后是一个正整数Q(Q<11),表示寻路的个数。
接下来Q行每行有2个正整数Start,End, 表示寻路的起终点。
Output
每个寻路要求打印一行,仅输出一个非负整数表示最佳路线的舒适度最高速与最低速的差。如果起点和终点不能到达,那么输出-1。
Sample Input
4 4
1 2 2
2 3 4
1 4 1
3 4 2
2
1 3
1 2
Sample Output
1
Submit
Status
Description
XX星有许多城市,城市之间通过一种奇怪的高速公路SARS(Super Air Roam Structure---超级空中漫游结构)进行交流,每条SARS都对行驶在上面的Flycar限制了固定的Speed,同时XX星人对 Flycar的“舒适度”有特殊要求,即乘坐过程中最高速度与最低速度的差越小乘坐越舒服 ,(理解为SARS的限速要求,flycar必须瞬间提速/降速,痛苦呀 ),
但XX星人对时间却没那么多要求。要你找出一条城市间的最舒适的路径。(SARS是双向的)。
Input
输入包括多个测试实例,每个实例包括:
第一行有2个正整数n (1<n<=200)和m (m<=1000),表示有N个城市和M条SARS。
接下来的行是三个正整数StartCity,EndCity,speed,表示从表面上看StartCity到EndCity,限速为speedSARS。speed<=1000000
然后是一个正整数Q(Q<11),表示寻路的个数。
接下来Q行每行有2个正整数Start,End, 表示寻路的起终点。
Output
每个寻路要求打印一行,仅输出一个非负整数表示最佳路线的舒适度最高速与最低速的差。如果起点和终点不能到达,那么输出-1。
Sample Input
4 4
1 2 2
2 3 4
1 4 1
3 4 2
2
1 3
1 2
Sample Output
1
0
思路:因为要求起点到终点的最小差值,用kruskal求最小生成树的思想,先把所有的边从小到大排好序,找最小生成树,当找到起点和终点在最小生成树里是就说明以及找到了以当前边为起点的最小值,其实最后的答案一定是在一个最小生成树里,这个最小生成树是(以起点或终点)为起点的边找到了(以起点或终点)为终点的边,然后这个最小值是
e[i].w -e[j].w
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = 22222222;
int n,m,fa[300];
struct Edge
{
int u,v,w;
}e[1200];
int cmp(const void *a, const void *b)
{
return ((Edge *)a) ->w - ((Edge *)b) ->w;
}
int find(int x)
{
int q = x;
while (q != fa[q])
{
q = fa[q];
}
int w = x;
while (w!= q)
{
x = fa[w];
fa[w] = q;
w = x;
}
return w;
}
void uni(int x,int y)
{
fa[y] = x;
}
int ans;
int f(int a,int b)
{
int i,j,k;
for(i = 0;i <=n;i++)
{
fa[i] = i;
}
qsort(e,m,sizeof(e[0]),cmp);
for(i = 0; i<m;i++) //枚举最小生成树的起始边
{
for(k = 0;k <=n;k++)
{
fa[k] = k;
}
for(j = i; j<m;j++)
{
int x = find (e[j].u);
int y = find (e[j].v);
if(x!=y)
{
uni(x,y);
if(find(a) == find(b)) //最小生成树里包含了起点跟终点
{
if(ans > e[j].w - e[i].w) //判断当前最小生成树里最小值和最大值的差是不是比之前找到的最大最小值得差小
ans = e[j].w - e[i].w;
break;
}
}
}
}
return ans;
}
int main()
{
while (scanf("%d %d",&n,&m)!=EOF)
{
int i,j;
for(i =0;i<m;i++)
{
scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].w);
}
int z,a,b;
cin>>z;
for(i = 0; i<z;i++)
{
ans = maxn;
cin>>a>>b;
int s = f(a,b);
if(s!=maxn)
cout<<s<<endl;
else
cout<<"-1"<<endl;
}
}
return 0;
}