zoukankan      html  css  js  c++  java
  • UVa 10801

    根据题意,以每一层楼为顶点,每个电梯可以到达的两层楼之间的秒数为每一条边的权值,以此构建一个无向图。然后利用dijkstra求出最短的时间,注意每次换乘电梯需要等待60s(因为同一个电梯上的楼层是相互可达的,所以我们只有通过另外一个电梯找到了更小的搭乘时间时候我们才会执行松弛操作),因此每转一个定点需要加60s时间(注意初始定点不需要60s的等待)。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int INF=0x3f3f3f3f;
    
    const int MAXN= 100 + 5 ;
    
    int speed[MAXN],floors[MAXN];//输入数据,
    int w[MAXN][MAXN],d[MAXN];//w是各点的权值 d是0到任意点的路径
    bool vis[MAXN];//vis是是否走过
    int n,k,num;
    
    void buildG(int ss)
    {
        for (int i=0; i<num; i++)
        {
            for (int j=i+1; j<num; j++)
            {
    
                //通过楼之差乘时间,求权值,取最短
                int dis=abs(floors[i]-floors[j])*speed[ss];
    
                //因为是双向的,所以如此建图
                if (dis<w[floors[i]][floors[j]])
                    w[floors[i]][floors[j]]=w[floors[j]][floors[i]]=dis;
    
            }
        }
    
    }
    
    
    //dij算法
    void dijk()
    {
        memset(vis,0,sizeof(vis));
    
        for (int i=0; i<100; i++)
        {
            d[i]=i==0?0:INF;
        }
    
    
        for (int i=0; i<100; i++)
        {
            int x,m=INF;
            for(int y=0; y<100; y++)
            {
                if (!vis[y]&&d[y]<m)
                {
                    m=d[x=y];
                }
            }
    
            vis[x]=true;
    
            for (int y=0; y<100; y++)
            {
                if (d[y]>d[x]+w[x][y]+60)
                {
                    d[y]=d[x]+w[x][y]+60;
                }
            }
    
    
        }
        if (d[k]==INF)
        {
            printf("IMPOSSIBLE
    ");
        }
        else
        {
            if (k==0)
                puts("0");
            else
                printf("%d
    ",d[k]-60);
        }
    
    }
    
    
    int main()
    {
        while(~scanf("%d%d",&n,&k))
        {
            memset(w,INF,sizeof(w));
            for (int i=0; i<n; i++)
            {
                scanf("%d",&speed[i]);
            }
    
            for (int i=0; i<n; i++)
            {
                num=0;
                
                //注意输入,这样处理很好,要借鉴
                while(true)
                {
                    scanf("%d",&floors[num++]);
                    if (getchar()=='
    ')
                        break;
                }
                buildG(i);
            }
            dijk();
        }
    
        return 0;
    }
  • 相关阅读:
    [转自老马的文章]用MODI OCR 21种语言
    [转老马的文章]MODI中的OCR模块
    贴片晶振的脚位方向如何区分
    晶振简介及如何使用示波器测试晶振
    Lintcode 150.买卖股票的最佳时机 II
    Lintcode 82.落单的数
    Lintcode 97.二叉树的最大深度
    Lintcode 9.Fizz Buzz 问题
    LeetCode之461. Hamming Distance
    NYOJ之题目325 zb的生日
  • 原文地址:https://www.cnblogs.com/s1124yy/p/5644413.html
Copyright © 2011-2022 走看看