• 极品飞车(并查集+枚举)


    极品飞车(并查集+枚举)

    Hecy被FC星人劫持了!

    “长的帅也是一种罪过吗?”,Hecy问劫持他的生物,结果被暴打。唉,原来Hecy被劫持的原因是FC星人看中了他的编程才能(“我真的长的不帅吗?”Hecy不死心地问另一个生物,结果再次被暴打)。

        FC星有许多城市,某些城市之间无法直接到达,但某些城市之间可以通过一种奇怪的高速公路SARS(Super Air Roam Structure 超级空中漫游结构)进行人员或物资的交流运输。在SARS上有且仅有一种“车”可以行驶,那就是传说中的极品飞车Flycar。东东们就是乘坐着Flycar在SARS上运动的。与地球相似地,每条SARS都对行驶在他上面的Flycars有限速要求——不同的是这既不是限最高速,也不是限最低速,而是限固定速,也就是说Flycars必须以所限速度行驶,否则就要被TS(Traffic System)来一次ts(tiger strike虎击)——这可不是好玩的!

    同时FC星人对flycar的“舒适度”也有特殊的要求。他们认为乘坐一次flycar过程中,flycar达到的最高速与最低速之间的差越小,本次乘坐越舒适(可以理解,因为SARS的限速要求,flycar都必须瞬间提/降速,痛苦啊)——FC星人对时间却没那么多要求。

    因此Hecy的任务就明确了:为FC星上几乎垄断了flycar市场的全星通用汽车公司(CC)设计新一代自动寻路flycar,使得该flycar能自动寻找两城市间最舒适的到达路径。

    任务

    对于给定的公路网以及两个城市s、t,求出从s到t的最舒适路径。

    输入

    输入数据的第一行两个正整数n、m(1<=n〈=200,1〈=m<=1000),n、m分别表示城市数和公路数。

    第二行是两个正整数s、t,表示初始城市和目标城市。

    接下来的n行每行三个正整数i、j、num(num〈=1000000),表示城市I,j之间有一条道路,该路的限时为num.

    输出

    输出数据的第一行为最舒适值。

    第二行依次输出最舒适路径上的城市。

    注意:如果有多个数据满足问题的要求,只要输出一个即可。

    样例输入

    2 1

    1 2

    1 2 1

    样例输出

    0

    1 2

    解题报告

    这一题和舒适的路径很像。主要要借助并查集。我们不妨把所有边按从小到大排序。并从小到达枚举边,将其作为最小边,依次按之后的边用并查集将点合并,直到起点与终点相连。这样,最高速度与最低速度的差就是所枚举的最小边与当前边的差。枚举出所有差,取最小值即可。这种解法与最小生成树有异曲同工之妙。

    #include<queue>
    #include <algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #define Pair pair<int,int>
    #define MAXN 1000+10
    #define MAXM 600000+1
    #define max(a,b) (a>b?a:b)
    #define min(a,b) (a<b?a:b)
    using namespace std;
    int n,m,num,s,t,pre[MAXN],v[MAXM],as;
    int fa[MAXM];
    struct Edge{
        int dis,next,to,exi,from;
    }edge[MAXM];
    bool cmp(Edge a,Edge b)
    {
        return a.dis<b.dis;
    }
    int find(int x)
    {
        if(fa[x]!=x) fa[x]=find(fa[x]);
        return fa[x];
    }
    void un(int x,int y)
    {
        
        fa[y]=x;
    }
    void work(int s,int t)
    {
        int mind=99999999,flag=0;
        for(int i=1;i<=m;i++)
        {
            for(int j=1;j<=n;j++) fa[j]=j;
            int minn=edge[i].dis,maxn=0;
            for(int j=i;j<=m;j++)
            {
                int a=find(edge[j].from),b=find(edge[j].to);
                if(a!=b)
                {
                    un(a,b);
                    maxn=edge[j].dis;
                    if(find(s)==find(t)) 
                    {
                        mind=min(mind,maxn-minn);
                        flag=1;
                        break;
                    }
                }
            }
            
        }
        if(mind!=99999999)
        printf("%d
    ",mind);
        else printf("-1
    ",mind);
    }
    int main()
    {
        freopen("flycar.in","r",stdin);
        freopen("flycar.out","w",stdout);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int x,y,z;
            scanf("%d%d%d",&edge[i].from,&edge[i].to,&edge[i].dis);
            
        }
        sort(edge+1,edge+1+m,cmp);
        scanf("%d",&as);
        for(int i=1;i<=as;i++)
        {
            scanf("%d%d",&s,&t);
            work(s,t);
        }
        
        return 0;
    }
  • 相关阅读:
    [Java] 计算两个日期之间的差(年 月 日)
    Javassist library is missing in classpath! Please add missed dependenc
    $_SERVER['SCRIPT_FILENAME'] 与 __FILE__ 区别
    内存管理一
    内存管理四
    内存管理二
    内存分配函数分类
    内存映像文件
    内存管理三
    到底有多少内存
  • 原文地址:https://www.cnblogs.com/yangyaojia/p/6346531.html
Copyright © 2020-2023  润新知