题目描述

现在城市有N个路口,每个路口有自己的编号,从0到N-1,每个路口还有自己的交通控制信号,例如0,3表示0号路口的交通信号每3个时刻变化一次,即0到3时刻0号路口允许通过,3到6时刻不允许通过,而6到9时刻又允许通过;以此类推,所有路口的允许通行都从时刻0开始。同时城市中存在M条道路将这N个路口相连接起来,确保从一个路口到另一个路口都可达,每条路由两个端点加上通行所需要的时间表示。现在给定起始路口和目的路口,从0时刻出发,请问最快能在什么时刻到达?

思路

由于Dijkstra算法每一步计算的都是从初始点到达各点之间的最短距离,这使得我们能够很容易计算在有信号灯的情况下通过路口需要在路口等待信号灯的时间,因此加入信号灯约束之后可对Dijkstra算法做如下改动即可:给定一个网络有节点集V,有向边集E,权重矩阵W,起点和终点分别为s和t,各路口信号灯变化周期为time。

初始化:标记节点集合为M,仅包含s;M中节点到V-M中节点的距离设为无穷大,初始节点到各节点的最短时间径记为dis,dis[s]=0;

step1:计算从M中各节点到V-M中各节点通行时间最小值,找到V-M中对应最短通行时间的节点并将其添加为标记节点,对应的最短通行时间为找到的最小值。

松弛:dis[j]= min{dis[j],  dis[i] + W[i, j] + wait[i, j]},其中wait为从i路口到通过j路口需要等待信号灯时间,计算方法为:如果j为终节点则等待时间为0[不用通过,到达即可]。

否则计算wait= (dis[i] + W[i, j])%(2*time[j]),如果wait小于time[j]则无需等待直接通过,否则需等待2*time[j]-wait。

step2:检查标记节点中是否包含t,如果是则终止,否则进入step1。

输入:

节点总数,节点的等待时间,边数,两个路口间的通行时间,s,t

9
0,3
1,5
2,7
3,3
4,5
5,7
6,9
7,3
8,5
14
0,1,4
0,7,8
1,2,8
1,7,11
2,3,7
2,5,4
2,8,2
3,4,9
3,5,14
4,5,10
5,6,2
6,8,6
6,7,1
7,8,7
0,4

输出:28

程序:

#include<stdio.h>
#include<string.h>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;#define ms(x, y) memset(x, y, sizeof(x))
#define mc(x, y) memcpy(x, y, sizeof(x))
const int inf = 0x3f3f3f3f;
const int N = 50;
int tm[N], dis[N], road[N][N];
bool vis[N];
int n;int dijkstra(int s, int t)
{ms(vis, false);ms(dis, inf);dis[s] = 0;while (true){int v = -1;for (int i = 0; i < n; i++)if (!vis[i] && (v == -1 || dis[v]>dis[i])) v = i;vis[v] = true;for (int i = 0; i < n; i++){if (!vis[i]){int wait = (dis[v] + road[v][i]) % (tm[i] * 2);if (wait < tm[i])wait = 0;   //不需等待else wait = tm[i] * 2 - wait;  //等待时间if (i == t) wait = 0;  //如果遇到终节点则无需等待if (dis[i] > dis[v] + road[v][i] + wait) // 松弛操作的变型dis[i] = dis[v] + road[v][i] + wait;}}if (v == t)break; // 终节点退出}return dis[t];
}int main()
{scanf("%d", &n);for (int i = 0; i < n; i++){int pos, time;scanf("%d,%d", &pos, &time);tm[pos] = time;}int m;scanf("%d", &m);ms(road, inf);for (int i = 0; i < m; i++){int from, to, need;scanf("%d,%d,%d", &from, &to, &need);road[from][to] = need;road[to][from] = need;}int s, t;scanf("%d,%d", &s, &t);printf("%d\n", dijkstra(s, t));return 0;
}

转载于:https://www.cnblogs.com/demian/p/7472492.html

带信号灯的最短路dijkstra问题(阿里巴巴2018校园招聘算法题)相关推荐

  1. 阿里巴巴2014校园招聘算法题

    题目:两个较长的单向链表a和b,为了找出节点node满足node in a 并且node in b.请设计空间使用尽量小的算法(用c/c++,java 或者伪代码) 思路:我们定义节点的距离为节点到链 ...

  2. 阿里巴巴2018校园招聘运筹优化算法工程师编程题

    对于考试向来都是后知后觉,过后留下一堆不甘与遗憾--然而不行就是不行,再接再厉. 声明:涉及阿里校招笔试,如有侵权,请联系我删除. 一.带信号灯的最短路问题 1. 题目描述 现在城市有N个路口,每个路 ...

  3. 阿里巴巴2008校园招聘在线宣讲会

    活动主题:阿里巴巴2008校园招聘在线宣讲会 活动时间: 2007年10月18日 18:30 - 20:30    主持人: 主持人 嘉宾: 阿里巴巴B2B技术部副总裁 李昂 阿里巴巴成立于1999年 ...

  4. 阿里巴巴2018实习生招聘 练习题

    ** 阿里巴巴2018实习生招聘 练习题 ** 1.平均速度最快的排序算法是? 答案:快速排序 解析:平均复杂度O(nlog(n)) 2.已有变量定义和函数调用语句, int a=25; print_ ...

  5. 阿里巴巴2015校园招聘面试大礼包

    1. 1. 阿里面试 1.1沈阳阿里2014校园招聘研发面试 日期:2013年9月 地点:沈阳 岗位:软件研发 收到通知是上午10点40的面试,因为面试地点在学校附近,所以早上9点就到了. 休息区等面 ...

  6. 阿里巴巴2010校园招聘技术类笔试试题

    阿里巴巴2010校园招聘技术类笔试试题 阿里巴巴2010校园招聘技术类笔试试题 卷I Java开发.测试工程师 1.       下列运算符中优先级别最高的是? A:& B:&& ...

  7. 阿里巴巴2015校园招聘面试经历(笔者面试问题----倾情奉献)

    8.29号笔试,9.1号官网显示笔试通过请预约面试时间,预约了9.17号下午三点面试. 投入更加紧张的准备中,先把项目中的各种可能被问到的细节问题想到,然后再总结自己当时的解决办法和思路.最后,把各种 ...

  8. 2014阿里巴巴秋季校园招聘-软件研发工程师笔试题/面试问题收集

    不属于冯诺依曼体系结构必要组成部分是: A.CPU B.Cache C.RAM D.ROM 关于排序算法的以下说法,错误的是: A.快速排序的平均时间复杂度O(nlogn),最坏O(N^2) B.堆排 ...

  9. 阿里巴巴2016校园招聘 研发工程师(四)详解

    ##单选题 #####1.一个长度为99的循环链表,指针A和指针B都指向了链表中的同一个节点,A以步长为1向前移动,B以步长为3向前移动,一共需要同时移动多少步A和B才能再次指向同一个节点____. ...

最新文章

  1. usaco ★Subset Sums 集合
  2. ubuntu1604编译android5.1(android L)失败error: unsupportedreloc 43等问题
  3. php自定义中文分词方法,一个用PHP写的中文分词函数_php
  4. php5.2 json,php5.2以上版本json_encode兼容性
  5. Josephus 线段数版
  6. 探讨微软团队开发利器VSTS安装及部署篇
  7. 【实战】Docker容器资源管理
  8. Iphone 铃声制作及同步
  9. 统计学中的十几个数据分析方法
  10. python 日程管理程序_729. 我的日程安排表(Python)
  11. Java 自定义Excel数据排序
  12. Flappy Bird游戏 C语言实现
  13. 赏帮赚,实战日记的第一天
  14. Win10问题篇之——WIN2016和WIN10关闭同步主机服务,节省磁盘频繁读取,并关闭自动维护
  15. 【一个故事讲完https】聊聊https的诞生
  16. C语言实现-求m到n之和
  17. 《STL源码剖析》笔记——allocator
  18. 菜鸟带你看源码——看不懂你打我ArrayList源码分析(基于java 8)
  19. 计算机应用基础模块四,计算机应用基础模块四PPT课件.ppt
  20. pda正常签收扫描是什么意思

热门文章

  1. 谈谈事件委托的理解?
  2. ctf-web-文件包含2
  3. Java基础算法题(02):古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?
  4. GEE学习笔记 九十二:Sentinel-2 最新去云方法总结
  5. Flink on RocksDB 参数调优指南
  6. 阿里MySQL 经理_我以为我对Mysql事务很熟,直到我遇到了阿里面试官!
  7. 年报背后:顺丰疯狂的错位价格战
  8. P1439 【模板】最长公共子序列
  9. android alarmmanager 闹钟,Android编程使用AlarmManager设置闹钟的方法
  10. CDA数据分析师深圳校区就业班第17期正式开班!