问题描述
何老板在今年的达喀尔汽车拉力赛中表现出色。现在还剩下最后一站的比赛,地图上总共有n(不超过500)个城市,最后一站的起点是1号城市,终点是n号城市。这些城市间有m(不超过10000)条道路相连接。何老板估计:因为是最后一站,所以选手们一定会选最近的道路行驶,所以这些道路上一定非常容易堵车。所以何老板决定选从起点到终点的第二短的道路行驶。问:第二短的道路是多长?
何老板选择的第二短的路径中,可以包含任何一条在最短路中出现的道路,并且,一条路可以重复走多次。当然咯,第二短路的长度必须严格大于最短路(可能有多条)的长度,但它的长度必须不大于所有除最短路外的路径的长度。
输入格式
第1行: 两个整数,n和m,用空格隔开
第2..m+1行: 每行包含三个用空格隔开的整数A、B和D,表示存在一条长度为D(1 <= D <= 5000)的路连接城市A和城市B
输出格式
1行: 输出一个整数,即城市1到城市N的第二短路的长度
样例输入
4 44
1 2 100
2 4 200
2 3 250
3 4 100
样例输出
450
友情提示: 该文章有多处“透明字”,请不要忽略任何一处“空白”
何老板yyds
----------------------------------------------------------------------------------------------------------- 华丽的分割线~
# 1.思路
次短路问题
最短路问题
图
如果你连最短路都不会,请先搞懂Floyd,DIjkstra( + 已死的SPFA)
如果你连图(论)是啥都不知道,请先了解图(论)
# 2.怎么写?
这里推荐Dijkstra,也只讲Dijkstra
Dijkstra求次短路
首先我们要开好数组
你需要结构体数组以链是向前星的存储(这种方式比二维数组好一些,数据大了二维数组还会爆)
一个ls数组,dis数组要开两个或者开二维,vis数组也要开二维
int ls[maxn];
long long dis[maxn][2];
bool vis[maxn][2];
//建议dis数组开long long
然后是输入,记住此题是无向边,要存两个方向的
Dijkstra函数部分
#伪代码
Dijkstra(s, e) {
int k,t,y,z,min;
初始化,初始化两维
dis[i][0] = dis[i][1] = inf;
vis[i][0] = vis[i][1] = 0;
dis[s][0]
do-while{ // 在此神奇地发现:不能用do-while,不知道为什么 因为我是蒟蒻 // 后来查了查,有,这种写法,大家可以参考参考
for (int i = 1; i <= n; i++) {
if (dis[i][0] < min && !vis[i][0]) {
……
t = 0
} else if (dis[i][1] < min && !vis[i][1]) {
……
t = 1
} //ps: if-else 语句中要加一个变量,看min是次短的还是最短的
}
if (k) {
v数组标记
while (j != 0) {
y = Map[j].y, z = Map[j].z;
如果min + z < dis[y][0] : dis[y][1] = dis[y][0]; dis[y][0] = min + z;
// 此时 最短路有最小的了,那么刚才的最短路就变成了次短路
否则 min + z > dis[y][0] 但 小于dis[y][1] :更新次短
j = Map[j].next;记得补一句
} // 等效于 (for (int j = last_side[u]; j; j = Map_of_side[j].next))
}
}
}
printf(dis[e][1]);
# 3.核心代码
你们滴缀爱(我能说我也爱吗?不能)
#核心代码
int k, t, y, z, min;
for (int i = 1; i <= n; i++) {
dis[i][0] = dis[i][1] = inf;
vis[i][0] = vis[i][1] = 0;
}
dis[s][0] = 0;
do {
k = 0;
min = inf;
for (int i = 1; i <= n; i++) {
if (dis[i][0] < min && !vis[i][0]) {
min = dis[i][0];
k = i;
t = 0;
} else if (dis[i][1] < min && !vis[i][1]) {
min = dis[i][1];
k = i;
t = 1;
}
}
if (k > 0) {
vis[k][t] = 1;
int j = ls[k];
while (j != 0) {
y = Map[j].y, z = Map[j].z;
if (min + z < dis[y][0]) {
dis[y][1] = dis[y][0];
dis[y][0] = min + z;
} else if ((min + z < dis[y][1]) && (min + z > dis[y][0])) {
dis[y][1] = min + z;
}
j = Map[j].next;
}
}
}while(k > 0);
想要完整代码?
啊哈哈哈哈哈哈!!被坑了吧
都给到这个份上了
没门!
THE END