zoukankan      html  css  js  c++  java
  • hdu 1598 find the most comfortable road(并查集+暴力搜索)

    find the most comfortable road

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


    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
     
    分析:
    (1)刚开始看到这道题时,首先想到的是搜索,于是乎就用了深度优先搜索,这是我的深搜的代码,无奈超时了,至于是否正确无法验证了,我觉得还凑活了,可是过不去(⊙o⊙)…
    深搜的代码(超时的),如果有高手用了深搜通过了,求指教啊,是否还有其他好的剪枝没想到呢????
    View Code
    #include <stdio.h>
    #include <string.h>
    //#define MAX_SPEED -1
    //#define MIN_SPEED 1000010
    
    int max_speed,min_speed,min;
    int n,m,q;
    int begin,end;
    int speed[210][210];
    int mark[210];
    
    //pos   pre
    void dfs(int pos,int maxs,int mins)
    {
        int i;
        for(i = 1;i<= n;i++)
        {
            if(mark[i]==1)continue;//访问过
            if(i==pos)continue;//自己
            if(speed[pos][i]==-1)continue;//不可直接到
            if(speed[pos][i]<mins)
            mins = speed[pos][i];
            if(speed[pos][i]>maxs)
            maxs = speed[pos][i];
            if(i==end)
            {
                if(maxs-mins<min)
                min = maxs-mins;
                return;
            }
            if(min==0)return;//如果已经找到最小的了,那么就返回
            mark[i]=1;
            dfs(i,maxs,mins);
            mark[i]=0;
        }
    }
    
    int main()
    {
    
        int x,y,sd;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            memset(speed,-1,sizeof(speed));
            memset(mark,0,sizeof(mark));
            for(int i=0;i<m;i++)
            {
                scanf("%d%d%d",&x,&y,&sd);
                speed[x][y]=speed[y][x]=sd;
            }
            scanf("%d",&q);
            while(q--)
            {
                scanf("%d%d",&begin,&end);
                mark[begin]=1;
                min = min_speed = 1000010;
                max_speed = -1;
                dfs(begin,max_speed,min_speed);
                if(min<1000010)
                printf("%d\n",min);
                else printf("-1\n");
            }
        }
        return 0;
    }

    (2)于是乎就上网查了这道题的解题报告,于是乎就是用并(查集+暴力搜索)这个居然过了。。。。。。。

    并查集:就是将能连通的城市合并为一个集合

    排序:按照路的限速从小到大排序

    暴力搜索:如果在某个集合下既有起始位置,又有终止位置,同时因为排序时从小到大排序的,所以直接用最后放进去的速度减去第一个放进去的速度即可。暴力的搜索一遍找出最符合条件的。

     
     
    View Code
    #include <stdio.h>
    #include <stdlib.h>
    #include <algorithm>
    using namespace std;
    typedef struct
    {
        int start,end;
        int length;
    }Edge;
    Edge edge[1010];
    int root[210];
    
    bool cmp(Edge a,Edge b)
    {
        return a.length<b.length;
    }
    
    int find_root(int a)
    {
        if(a==root[a])return a;
        return root[a] = find_root(root[a]);
    }
    
    int main()
    {
        int n,m,q;
        int begin,end;
        int min;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            for(int i=0;i<m;i++)
            scanf("%d%d%d",&edge[i].start,&edge[i].end,&edge[i].length);
            sort(edge,edge+m,cmp);
            scanf("%d",&q);
            while(q--)
            {
                int fx,fy;
                min = 1000010;
                scanf("%d%d",&begin,&end);
                for(int k=0;k<m;k++)
                {
                    int i;
                    for(i=0;i<=n;i++)
                    root[i]=i;
                    for(i=k;i<m;i++)
                    {
                        fx = find_root(edge[i].start);
                        fy = find_root(edge[i].end);
                        if(fx!=fy)
                        root[fy] = fx;
                        if(find_root(begin)==find_root(end))
                        break;
                    }
                    if(i==m)break;
                    if(edge[i].length-edge[k].length<min)
                    min = edge[i].length-edge[k].length;
                }
                if(min<1000010)
                printf("%d\n",min);
                else printf("-1\n");
            }
        }
        return 0;
    }
     
  • 相关阅读:
    IntelliJ IDEA 2017 注册方法
    WindowsAll下安装与破解IntelliJ IDEA2017
    JPA的一对多映射(双向)关联
    JPA 单向一对多关联关系
    JPA 映射单向多对一的关联关系
    关于数据库主键和外键
    JPA(API)
    X509 文件扩展名
    linux设置支持中文
    wp8安装SSL证书
  • 原文地址:https://www.cnblogs.com/newpanderking/p/2731300.html
Copyright © 2011-2022 走看看