您的位置:首页 > 其它

uva10801(最短路问题)

2016-03-10 20:42 92 查看
题目大意:

有一层不超过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
,g

,T
;
int num
;
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
;
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

, arr
, d
;
bool vis
;

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: