贝茜把家搬到了一个小农场,但她常常回到 FJ 的农场去拜访她的朋友。贝茜很喜欢路边的风景,不想那么快地结束她的旅途,于是她每次回农场,都会选择第二短的路径,而不象我们所习惯的那样,选择最短路。
贝茜所在的乡村有 R(1≤R≤10^5)条双向道路,每条路都连接了所有的 N(1≤N≤5000)个农场中的某两个。贝茜居住在农场 1,她的朋友们居住在农场 N(即贝茜每次旅行的目的地)。
贝茜选择的第二短的路径中,可以包含任何一条在最短路中出现的道路,并且一条路可以重复走多次。当然第二短路的长度必须严格大于最短路(可能有多条)的长度,但它的长度必须不大于所有除最短路外的路径的长度。
严格次短路
首先我们要明确,最短路只能从最短路转移过来
但是次短路可以从最短路或次短路转移过来
然后我们在Dij中记录一个最短路
然后此题有一个坑点,就是可以重复走
例如:
这个图的最短路是1,次短路是3,从1到2再到1再到2
所以为了转移,我们在开始的时候就要把从1到1的此段路赋为正无穷,否则无法支持从2再走回来
下面给出代码:
#include<iostream> #include<cmath> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<algorithm> #include<queue> using namespace std; inline int rd(){ int x=0,f=1; char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; return x*f; } inline void write(int x){ if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); return ; } struct node{ int u,v; int set; bool operator<(const node x) const{return u>x.u;} }; int head[100006],nxt[200006],to[200006],v[200006]; int total=0; void add(int x,int y,int z){ total++; to[total]=y; v[total]=z; nxt[total]=head[x]; head[x]=total; return ; } int n,m; priority_queue <node> Q; int dis[100006],dis2[100006]; int book[100006]; int vis[100006]; void dij(int x){ memset(dis,127,sizeof(dis)); memset(dis2,127,sizeof(dis2)); dis[x]=0; node h; h.v=x,h.u=0; Q.push(h); while(!Q.empty()){ node h=Q.top(); Q.pop(); if(book[h.v]&&vis[h.v]) continue; if(h.set==1) book[h.v]=1; else vis[h.v]=1; for(int e=head[h.v];e;e=nxt[e]){ dis2[to[e]]=min(dis2[to[e]],dis2[h.v]+v[e]); if(dis[to[e]]>dis[h.v]+v[e]){ dis2[to[e]]=dis[to[e]]; dis[to[e]]=dis[h.v]+v[e]; node k; k.v=to[e],k.u=dis[to[e]],k.set=1; Q.push(k); } else if(dis2[to[e]]>dis[h.v]+v[e]&&dis[h.v]+v[e]>dis[to[e]]){ dis2[to[e]]=dis[h.v]+v[e]; node k; k.v=to[e],k.u=dis2[to[e]],k.set=2; Q.push(k); } if(dis2[h.v]+v[e]>dis[to[e]]) dis2[to[e]]=min(dis2[to[e]],dis2[h.v]+v[e]); } } return ; } int main(){ n=rd(),m=rd(); for(int i=1;i<=m;i++){ int x=rd(),y=rd(),z=rd(); add(x,y,z),add(y,x,z); } dij(1); write(dis2[n]); return 0; }