find the most comfortable road
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5760 Accepted Submission(s): 2492
Problem Description
XX星有许多城市,城市之间通过一种奇怪的高速公路SARS(Super Air Roam Structure---超级空中漫游结构)进行交流,每条SARS都对行驶在上面的Flycar限制了固定的Speed,同时XX星人对 Flycar的“舒适度”有特殊要求,即乘坐过程中最高速度与最低速度的差越小乘坐越舒服 ,(理解为SARS的限速要求,flycar必须瞬间提速/降速,痛苦呀 ),
但XX星人对时间却没那么多要求。要你找出一条城市间的最舒适的路径。(SARS是双向的)。
但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, 表示寻路的起终点。
第一行有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
4 4
1 2 2
2 3 4
1 4 1
3 4 2
2
1 3
1 2
Sample Output
1
0
Author
ailyanlu
Source
尝试用广搜写了一发,WA了,后来想到了会不会有一条边重复走的情况,然后我在访问次数限制上边加大,还是wa,可惜一直到TLE了都没能够AC,看来这个特殊情况的数据真是过不掉啊。。。。。
思路:
我们要得到min【all the way】(最大速度-最小的速度),首先我们通过对边权值的排序可以很容易就找到这个最小速度,但是就这个最大速度而言,我们要找到相对最小,而且我们最终得到的结果是相减值的最小,我们直接贪心很难贪心到点子上,所以我们不如枚举起点边,然后根据最小生成树的思路,继续从小到大的值建树,建到如果find(起点)==find(终点)的时候,我们也就找到了这种走法的最大边权值,也就是最后建的一条边,然后我们ans=min(ans,最后边权值-起点边权值)即可,然后我们枚举所有的起点边,总能够找到最终解。
AC代码:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
struct path
{
int x,y,w;
}a[1212];
int f[250];
int cmp(path a,path b)
{
return a.w<b.w;
}
int find(int a)
{
int r=a;
while(f[r]!=r)
r=f[r];
int i=a;
int j;
while(i!=r)
{
j=f[i];
f[i]=r;
i=j;
}
return r;
}
void merge(int a,int b)
{
int A,B;
A=find(a);
B=find(b);
if(A!=B)
f[B]=A;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w);
}
sort(a,a+m,cmp);
int q;
scanf("%d",&q);
while(q--)
{
int ans=0x3f3f3f3f;
int u,v;
scanf("%d%d",&u,&v);
for(int i=0;i<m;i++)
{
for(int j=0;j<=n;j++)f[j]=j;
for(int j=i;j<m;j++)
{
merge(a[j].x,a[j].y);
if(find(u)==find(v))
{
ans=min(ans,a[j].w-a[i].w);
}
}
}
if(ans!=0x3f3f3f3f)
printf("%d\n",ans);
else
printf("-1\n");
}
}
}