见了这么多最短路题,来一道次短路!!!
新冠病毒要回家.
题意:
n个点,m条边,求0到n-1的次短路。
分析:
在最短路的基础上开一个dis2数组记录次短路长度,当需要更新最短路时,把当前最短路的值赋给次短路,然后再更新最短路的值,另外,当前的值比最短路长且比次短路短时,更新次短路的值。
基本代码与最短路一致。
代码
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
#define mp make_pair
#define pb push_back
#define __T int T; scanf("%d",&T);while(T--)
const ll mod=1e9+7;
const int maxn = 1e5 + 5;
struct edge{
int to;
int nxt;
int w;
}e[maxn*2];
struct node{
int to;
int w;
bool operator<(const node &a) const{
return w > a.w;
}
};
int n,m;
int cnt = 0;
int head[maxn];
int dis1[maxn];
int dis2[maxn];
void add(int u, int v, int w){
e[cnt].w = w;
e[cnt].to = v;
e[cnt].nxt = head[u];
head[u] = cnt ++;
}
void dij(){
priority_queue<node> q;
q.push({0,0});
dis1[0] = 0;
while(!q.empty()){
node p = q.top();
q.pop();
int u = p.to;
int d = p.w; //注意这里p.w和dis1[v]不一定相同,和最短路有区别
if(d > dis2[u]) continue; //减枝
for(int i = head[u]; i != -1; i = e[i].nxt){
int v = e[i].to;
if(dis1[v] > e[i].w + d){ //找到比最短路更短的
dis2[v] = dis1[v]; //先把之前的最短路赋值给次短路
dis1[v] = e[i].w + d; //更新最短路
q.push({v,dis1[v]});
}else if(dis2[v] > e[i].w + d){ //比最短路长且比次短路短
dis2[v] = e[i].w + d;
q.push({v,dis2[v]});
}
}
}
}
int main(){
scanf("%d %d", &n, &m);
for(int i = 0; i <= n; i ++){
head[i] = -1;
dis1[i] = inf;
dis2[i] = inf;
}
while(m--){
int u,v,w;
scanf("%d %d %d", &u, &v, &w);
add(u,v,w);
add(v,u,w);
}
dij();
printf("%d\n", dis2[n-1]);
return 0;
}
代码就这么简单,但是感觉碰到变式还是不会做,😫