HDU - 1598 find the most comfortable road(贪心枚举+最小生成树kruskal)

14 篇文章 0 订阅
6 篇文章 0 订阅

点击打开题目链接

find the most comfortable road

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7115    Accepted Submission(s): 3037

Problem 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

Author

ailyanlu

Source

Recommend

8600   |   We have carefully selected several similar problems for you:   1596  1217  1142  1385  1690 

Statistic | Submit | Discuss | Note

基础的kruskal肯定没问题了,这个题新意在于需要枚举,找存在使速度差最小的路径。

思路:基础并查集+kruskal算法+贪心枚举,因为要找速度差最小,所以速度从小到大排序,然后从第一条路径 开始进行枚举,直到找到开始点与结束点父节点相同的路径 j 则说明相通,然后用 j 的速度减去 i 的速度即为最大速度差,然后再以第二条路径为 i 往后依次枚举。一开始WA因为sort忘记+1,因为cnt从1开始,还要注意结构体范围。

附上AC代码:

#include<iostream>
#include<cstdio>
#include<algorithm>

using namespace std;
const int maxn=200+5;
const int INF=0x7f7f7f7f;
int par[maxn];
int N,M,Q;
int s,e;
int min_;

struct edges{
int startcity,endcity,speed;
}edge[maxn*maxn];

bool cmp(const edges a,const edges b)
{
    return a.speed<b.speed;
}
void init()
{
    for(int i=1;i<=N;i++)
        par[i]=i;
}

int find(int a)
{
    if(a==par[a])return a;
    return par[a]=find(par[a]);
}

void kruskal(int cnt,int a,int b)
{
    for(int i=1;i<=cnt;i++)
    {
        init();
        for(int j=i;j<=cnt;j++)
        {
            int fx=find(edge[j].startcity);
            int fy=find(edge[j].endcity);
            if(fx!=fy)
            {
                if(fx>fy)
                    par[fx]=fy;
                else
                    par[fy]=fx;
            }
            if(find(a)==find(b))
            {
                min_=min(min_,edge[j].speed-edge[i].speed);
                break;
            }
        }
    }
}

int main()
{
    while(~scanf("%d%d",&N,&M))
    {
        cnt=1;
        while(M--)
            scanf("%d%d%d",&edge[cnt].startcity,&edge[cnt].endcity,&edge[cnt++].speed);

        sort(edge+1,edge+cnt+1,cmp);
        scanf("%d",&Q);
        while(Q--)
        {
            scanf("%d%d",&s,&e);
            min_=INF;
            kruskal(cnt,s,e);
            if(min_==INF)printf("-1\n");
            else printf("%d\n",min_);
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chook_lxk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值