题目描述
小明是今年参加复试的外校考生,他要去民主楼小礼堂签到。由于对中南大学校本部很不熟悉,小明找到了这边读书的好朋友鲁大师,不巧,鲁大师在忙着自由探索项目的结题工作,不能给他带路,只好给他发了一份半成品的电子地图。地图上只列出了校本部内的N个点,M条路,小明处于S点,民主楼小礼堂是T点。小明感谢鲁大师,当然只是在拿到地图的一瞬间,后面的情况让他知道这半成品到底有多坑。鲁大师制作的电子地图是带有语音提示功能的,但是在编号为奇数的点他要等1分钟才能告诉他具体怎么走,而在编号为偶数的点要等2分钟。现在告诉你地图的具体情况,小明想知道他能不能在A分钟内赶到民主楼小礼堂。
输入
输入数据有多组,每组占M+1行,第一行有5个数字N,M,S,T,A,接下来M行,每行三个数字u,v,t,代表每条路的两个顶点和步行时间。(输入数据保证不含重边0<N<M<1000)
输出
对于每组输入数据,输出一行,小明能在A分钟内赶到民主楼小礼堂输出YES和总共花费的时间,否则输出KENG
样例输入
4 3 1 4 10
1 2 1
3 2 2
3 4 3
5 4 2 4 7
1 2 5
5 4 2
3 5 1
2 3 1
样例输出
YES 10
KENG
分析:
单源最短路径问题,用Dijkstra算法即可,注意不要忘了等待语音的时间。
#include<bits/stdc++.h>
using namespace std;
int N, M, S, T, A;
int maze[1010][1010];
int min_t[1010];
bool vis[1010];
void dijkstra(){
int cur = S;
min_t[cur] = 0;
vis[cur] = true;
for(int i = 0; i < N - 1; i++){
//slack
int extra_t = cur % 2 == 0 ? 2 : 1;
for(int j = 1; j <= N; j++){
if(maze[cur][j] != 0 && !vis[j] && min_t[cur] + extra_t + maze[cur][j] < min_t[j])
min_t[j] = min_t[cur] + extra_t + maze[cur][j];
}
//pick the nearest one
int index = 0, minimum = INT_MAX;
for(int j = 1; j <= N; j++){
if(min_t[j] != INT_MAX && !vis[j] && min_t[j] < minimum){
index = j;
minimum = min_t[j];
}
}
if(index == 0) return;
else{
vis[index] = true;
cur = index;
}
}
}
int main(){
while(cin >> N >> M >> S >> T >> A){
int u, v, t;
fill(vis, vis + 1010, false);
fill(min_t, min_t + 1010, INT_MAX);
fill(maze[0], maze[0] + 1010 * 1010, 0);
for(int i = 0; i < M; i++){
cin >> u >> v >> t;
maze[u][v] = t;
maze[v][u] = t;
}
dijkstra();
if(min_t[T] <= A) cout << "YES " << min_t[T] << endl;
else cout << "KENG" << endl;
}
return 0;
}