大意:给定一定的电梯以及电梯可以到达的楼层,求坐电梯到特定的位置最小的时间。

思路:

1、建立无向图,明确一个电梯上的楼层是相互可达的,以每一个楼层代表一个顶点建图。

2、由于换乘电梯需要60s,那么什么时候换乘电梯呢?由于同一个电梯上的楼层是相互可达的,所以我们只有通过另外一个电梯找到了更小的搭乘时间时候我们才会松弛。

3、上第一个电梯时是不需要时间的,为了Dijkstra处理方便,我们加上,我们最后减去60即可。

4、松弛时判断的条件是d[y] > d[x] + w[x][y] + 60。

 

CODE:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
using namespace std;

#define MAXN 110
#define INF 0x3f3f3f3f
int w[MAXN][MAXN];
int d[MAXN];
int num[MAXN], Time[MAXN];

int n, m, k, tot;

void read_graph(int index)
{
    for(int i = 0 ; i < tot; i++)
    {
        for(int j = 0; j < tot; j++) if(i != j)
        {
            int t = abs(num[i]-num[j])*Time[index];
            if(t < w[num[i]][num[j]])
            {
                w[num[i]][num[j]] = w[num[j]][num[i]] = t;
            }
        }
    }
}

void init()
{
    memset(w, INF, sizeof(w));
    memset(Time, 0sizeof(Time));
    memset(num, 0sizeof(num));
    
}

void Dijkstra(int src)
{
    bool vis[MAXN] = {0};
    for(int i = 0; i < 100; i++) d[i] = (i == src)? 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] = 1;
        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\n");
    }
    else
    {
        if(k == 0) printf("0\n");
        else printf("%d\n", d[k]-60);    //减去出发的点。 
    }
}


int main()
{
    while(~scanf("%d%d", &n, &k))
    {
        init();
        for(int i = 0; i < n; i++) scanf("%d", &Time[i]);
        for(int i = 0; i < n; i++)
        {
           memset(num, 0sizeof(num));
           tot = 0;
            do
            {
                scanf("%d", &num[tot++]);
            }while(getchar() != '\n');
           read_graph(i);
        }
        Dijkstra(0);
    }
    return 0;
}

 

 

posted on 2012-10-25 13:32  有间博客  阅读(235)  评论(0编辑  收藏  举报