题目含义
一个人想去朋友家,最短路不走,想走次短路,而且长度严格小于最短路
题目分析
次短路的模板题,还是挺简单的
但是与求最短路不同
Dijstra算法里此时队列中dis最小的点的dis即是它的最短路,就将它出队处理接下来的点就行了
而求次短路时,如果这个点像求最短路一样出队的话,万一这个点的次短路没求好
那完了,你已经出队了
而且,你队列里装的dis不是指对应pos的最短路,而是指某一条可以到pos的路径长度(可能是最短路,可以是次短路,在一些求第k短时甚至可能是其他短路)
所以就不能像求最短路一样直接用dis[pos]代指(q.top()).dis而只能用(q.top()).dis
题目代码
#include<iostream> #include<stdio.h> #include<string.h> #include<queue> using namespace std; const int maxn=1e5+7; const int INF=0x3f3f3f3f; typedef long long LL; int head[5007],dis[5007][2];///dis[i][0]表示最短路,dis[i][1]表示次短路 int tot,n,r,a,b,d; struct edge{ int to,w,next; }e[maxn*2]; struct node{ int pos,dis; bool operator<(const node &x)const{ return dis>x.dis; } }; void add(int u,int v,int w){ e[tot].to=v; e[tot].w=w; e[tot].next=head[u]; head[u]=tot++; } void Dijkstra(){ priority_queue<node>q; dis[1][0]=0; q.push((node){1,0}); while(!q.empty()){ node temp=q.top();q.pop(); int u=temp.pos,dist=temp.dis; for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].to; if(dis[v][0]>dist+e[i].w){ dis[v][1]=dis[v][0]; dis[v][0]=dist+e[i].w; q.push((node){v,dis[v][0]}); q.push((node){v,dis[v][1]}); } else if(dis[v][1]>dist+e[i].w&&dis[v][0]!=dist+e[i].w){ dis[v][1]=dist+e[i].w; q.push((node){v,dis[v][1]}); } } } } int main(){ scanf("%d%d",&n,&r); tot=0; memset(head,-1,sizeof(head)); memset(dis,INF,sizeof(dis)); for(int i=1;i<=r;i++){ scanf("%d%d%d",&a,&b,&d); add(a,b,d),add(b,a,d); } Dijkstra(); printf("%d\n",dis[n][1]); return 0; }