2015中南大学上机(五)-好坑的电子地图

任何疑问、意见、建议请留言公众号:一航代码

小明是今年参加复试的外校考生,他要去民主楼小礼堂签到。由于对中南大学校本部很不熟悉,小明找到了这边读书的好朋友鲁大师,不巧,鲁大师在忙着自由探索项目的结题工作,不能给他带路,只好给他发了一份半成品的电子地图。地图上只列出了校本部内的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

解决方法:

(1)算法思想:

考察Dijkstra算法。需注意在编号为奇数的点他要等1分钟才能告诉他具体怎么走,而在编号为偶数的点要等2分钟。

(2)代码实现:

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <math.h>
using namespace std;
//@一航代码
const int inf = 99999999;//不可到达
int main()
{

    int n, m, s, t, a;
    while (cin >> n >> m >> s >> t >> a)
    {
        vector<vector<int>> e(n + 2, vector<int>(n + 2)); //邻接矩阵
        vector<int> dis(n + 2, inf);                      //保存到t点的路程
        vector<bool> visit(n + 2, false);                 //标记当前节点是否访问过
        for (int i = 1; i <= n; i++)                      //初始化二维数组,对角线被初始化为0
        {
            for (int j = 1; j <= n; j++)
            {
                if (i == j)
                {
                    e[i][j] = e[j][i] = 0;
                }
                else
                {
                    e[i][j] = e[j][i] = inf;
                }
            }
        }
        for (int i = 0; i < m; i++)
        {
            int n1, n2, c;
            cin >> n1 >> n2 >> c;
            e[n1][n2] = e[n2][n1] = c;
        }

        dis[s] = 0;           //表示从出发点到i节点的距离             //Dijkstra算法部分
        int wait = 0, u = -1; //在奇数顶点等1分钟,在偶数顶点等2分钟
        for (int i = 1; i <= n; i++)
        {
            int minn = inf;
            for (int j = 1; j <= n; j++)
            {
                if (visit[j] == false && dis[j] < minn) //更新dis数组
                {
                    u = j;
                    minn = dis[j];
                }
            }
            if (u == -1) //重要,u=-1表示未找到最短路径
            {
                break;
            }
            visit[u] = true; //开始访问u顶点
            if (u % 2 == 0)  //在奇数顶点等1分钟,在偶数顶点等2分钟
            {
                wait = 2;
            }
            else
            {
                wait = 1;
            }
            for (int v = 1; v <= n; v++) //进行松弛操作的判定,注意wait
            {
                if (visit[v] == false && e[u][v] != inf && dis[u] + e[u][v] + wait < dis[v])
                {
                    dis[v] = dis[u] + e[u][v] + wait;
                }
            }
        }
        if (dis[t] <= a)
        {
            cout << "YES " << dis[t] << endl;
        }
        else if (dis[t] > a || u == -1)
        {
            cout << "KENG" << endl;
        }
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值