题目传送门
这是一道很经典的最短路问题
因为数据范围较小,所以不用邻接表的SPFA也不会MLE
#include<bits/stdc++.h>
using namespace std;
int a[120][120];
//a[i][j]代表从i到j的路程(-1表示没路)
int h[8] = {0,2,6,4,8,6,10,14};
//h代表每种地形所需时间
queue<int> q; //队列
int s,e;//起点和终点
int dis[120]; //dis[i]代表点i到起点的最短时间
bool used[120] = {0}; //防止元素重复入队
int main(){
memset(a,-1,sizeof(a));
memset(dis,-1,sizeof(dis));
bool flag;
for(int i = 1;i<=7;i++){
scanf("%d",&flag);
if(flag==1)h[i]/=2;
}//如果有魔法石则时间减半
scanf("%d%d",&s,&e);
int n;
scanf("%d",&n);
int ai,bi,ti;
for(int i = 1;i<=n;i++){
scanf("%d%d%d",&ai,&bi,&ti);
a[ai][bi] = h[ti];
a[bi][ai] = h[ti];
//注意是无向图,要建立双向边(如果不建立双向边只有20分,我为此提交了4遍才过)
}
q.push(s);
//起点入队
dis[s] = 0;
while(!q.empty()){ // 裸的SPFA
int nw = q.front();
for(int i = 1;i<=101;i++){
if(a[nw][i]==-1)continue;
int rd = dis[nw]+a[nw][i];//rd为经过nw到a的最短时间
if(dis[i]==-1){ //如果这个点是第一次搜索到
dis[i] = rd;
q.push(i);
used[i] = 1;
}else{ //否则比较dis[i]和rd大小
if(dis[i]<=rd)continue;
dis[i] = rd;
if(!used[i]){
q.push(i);
used[i] = 1;
}
}
}
q.pop();
used[nw] = 0;
}
printf("%d",dis[e]);
//输出终点到起点的最短时间
return 0;
}
原文地址:https://www.cnblogs.com/LJA001100/p/10359572.html
时间: 2024-10-03 01:37:27