find the most comfortable road
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2724 Accepted Submission(s): 1158
但XX星人对时间却没那么多要求。要你找出一条城市间的最舒适的路径。(SARS是双向的)。
第一行有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, 表示寻路的起终点。
4 4 1 2 2 2 3 4 1 4 1 3 4 2 2 1 3 1 2
1 0
#include <iostream>
#include <algorithm>
using namespace std;
int father[222]; //记录每个元素的指向
struct ssss
{
int x,y,s;
}ss[1111];
int Find(int x)
{
return x==father[x]?x:father[x]=Find(father[x]); //找祖先,并进行路径压缩
}
void Union(int i)
{
father[Find(ss[i].x)]=Find(ss[i].y); //这是流氓式的修路,也就是说没管你通没通都修你一遍,反正不影响连通的判断
}
bool cmp(const ssss &a,const ssss &b)
{
return a.s<b.s; //升序排序
}
int main (void)
{
int i,j,k,l,n,m,x,y,sum;
while(cin>>n>>m)
{
for(i=0;i<m;i++)
cin>>ss[i].x>>ss[i].y>>ss[i].s;
sort(ss,ss+m,cmp); //在外面就排序做好准备
cin>>l;
while(l--&&cin>>x>>y)
{
for(i=0,sum=1000001;i<m;i++) //选择起点
{
for(j=0;j<222;j++)father[j]=j; //每次都要初始化father数组
for(j=i;j<m;j++) //从起点开始修路
{
Union(j); //把路能修的就修起来
if(Find(x)==Find(y))break; //当起点和终点已经连通,那么就跳出
}
if(j==m)break; //连通后悔跳出来,跳出来就不会有j==m-1
if(sum>ss[j].s-ss[i].s)sum=ss[j].s-ss[i].s; //是按照速度递增的方式来并查的,所以最小和最大速度就是起点和终点,整个过程是越来越不舒服******这是精华地点
}
if(sum<1000001)cout<<sum<<endl;
else cout<<"-1"<<endl;
}
}
return 0;
}
虽然这个题我是实在怕麻烦所以找的别人的思路来的,不过关键的就是理解,有时候过程在结果面前也会逊色几分,那么就来说说我对这个题的看法,这种做法是巧用了最值,起点取的是最小速度,终点当然就是最大的啦,然后因为过程中速度智慧递增,所以啊,你一个一个速度的差值来加和直接起点到终点的差值是一样的,这样就方便了太多了,我觉得这个题就这点是有点值得深思的,其他的?太水了