uva10801(最短路问题)

题目大意:
有一层不超过100层的大楼, 有n个电梯,它们的速度都不同。 而且每个电梯只能到达指定的那些楼层,而且它们都有各自的速度(即上升一层或下降一层所用的时间)。 如果一个人在某层走出电梯,要换一个电梯乘,那么他要等60秒(不管要等的是那个电梯,即使是刚刚出来的那个电梯也要等60秒)。在0层搭电梯出发时不需要等待。
一个人从0层开始,目的地是k层, 现在要搭这些电梯,问最少需多少时间。

思路:
dijkstra算法+ 邻接矩阵
用g数组保存从i到j需要使用的最短时间。
用d数组保存从0到i需要使用的最短时间。
然后根据dijkstra算法进行计算就可以了。

邻接矩阵代码:

#include <iostream>
using namespace std;
#include <cstring>
#include <stdio.h>
#include <algorithm>
const int N =105;
const int INF = 0x3f3f3f3f;
int n,k,d[N],g[N][N],T[N];
int num[N];
void add(int a,int b,int c) {
    int dis = abs(b - a) * c;
    if(g[a][b] > dis)
        g[a][b] = g[b][a] = dis;
}
void solve() {
    int vis[N];
    memset(vis,0,sizeof(vis));
    for(int i = 0; i < 99; i++) {
        int x,m = INF,flag = 0;
        for(int j = 0; j < 100; j++) {
            if(!vis[j] && d[j] < m) {
                m = d[j];
                x = j;
                flag = 1;
            }
        }
        if(!flag)
            return;
        vis[x] = 1;
        for(int j = 0; j < 100; j++)
            if(!vis[j] && d[j] > d[x] + g[x][j] + 60)
                d[j] = d[x] + g[x][j] + 60;
    }
}
int main() {

    while(scanf("%d %d",&n,&k) != EOF) {
        for(int i = 0 ; i < n; i++) 
            scanf("%d",&T[i]);

        memset(d,INF,sizeof(d));
        memset(g,INF,sizeof(g));
        d[0] = 0;
        for(int i = 0; i < n; i++) {
            int j = 0;
            do {
                scanf("%d",&num[j++]);
                }while(getchar() != '\n');
            for(int q = 0; q < j ; q++)
                for(int p = 0; p < q; p++)
                    add(num[q],num[p],T[i]);
        }
        solve();
        if(k == 0)
            printf("0\n");
        else if(d[k] == INF)
            printf("IMPOSSIBLE\n");
        else
            printf("%d\n",d[k] - 60);
    }
    return 0;
}

SPFA以及dijkstra算法(别人的代码):

#include<cstdio> 
#include<cmath> 
#include<cstring> 
#include<queue> 
#include<utility> 
using namespace std;  

typedef pair<int,int>pii;  
priority_queue<pii,vector<pii>,greater<pii> >q;  

const int N   = 105;  
const int INF = 1000000000;  
int n, k, T[6], w[N][N], arr[N], d[N];  
bool vis[N];  



inline void read_graph(){  
    for(int i=0; i<N; ++i){  
        w[i][i] = INF;  
        for(int j=i+1; j<N; ++j)  
            w[i][j]=w[j][i]=INF;  
    }  
    for(int i=0; i<n; ++i)  
        scanf("%d",&T[i]);  

    char ch;  
    for(int i=0; i<n; ++i){  
        int pos=0;  
        do{  
            scanf("%d",&arr[pos++]);  
        }while(getchar()!='\n');  

        for(int j=0; j<pos; ++j){  
            for(int k=j; k<pos; ++k){  
                int tmp=abs(arr[j]-arr[k])*T[i];  
                if(tmp<w[arr[j]][arr[k]]){  
                    w[arr[j]][arr[k]] = w[arr[k]][arr[j]] = tmp;  
                }  
            }  
        }  
    }  
}  

inline void SPFA(int src){  
    memset(vis, 0, sizeof(vis));  
    for(int i=0; i<N; ++i) d[i]=INF;  
    d[src] = 0;  
    queue<int>q;  
    q.push(src);  
    while(!q.empty()){  
        int u=q.front(); q.pop();  
        vis[u] = false;  
        for(int i=0; i<N; ++i){  
            if(u==0){  
                if(d[i]>d[u]+w[u][i]){  
                    d[i] = d[u]+w[u][i];  
                    if(!vis[i]){  
                        vis[i] = true;  
                        q.push(i);  
                    }  
                }  
            }  
            else if(d[i]>d[u]+w[u][i]+60){  
                d[i] = d[u]+w[u][i]+60;  
                if(!vis[i]){  
                    vis[i] = true;  
                    q.push(i);  
                }  
            }  
        }  
    }  
}  

inline bool Dijkstra(int src){  
    for(int i=0; i<N; ++i) d[i] = INF;  
    d[src] = 0;  

    q.push(make_pair(d[src], src));  
    while(!q.empty()){  
        pii t=q.top(); q.pop();  
        int u=t.second;  
        if(t.first!=d[u]) continue;  
        for(int v=0; v<N; ++v){  
            if(u==0){  
                if(d[v]>d[u]+w[u][v]){  
                    d[v] = d[u]+w[u][v];  
                    q.push(make_pair(d[v],v));  
                }  
            }  
            else{  
                if(d[v]>d[u]+w[u][v]+60){  
                    d[v]=d[u]+w[u][v]+60;  
                    q.push(make_pair(d[v],v));  
                }  
            }  
        }  
    }  
}  
int main(){  
    while(~scanf("%d%d",&n,&k)){  
        read_graph();   
    // SPFA(0); 
         Dijkstra(0);  
        if(d[k]!=INF) printf("%d\n", d[k]);  
        else printf("IMPOSSIBLE\n");  
    }  
    return 0;  
}  

你可能感兴趣的:(uva10801(最短路问题))