题意:求次短路
分析:d2[n] :1 --> n的次短路
d1[n] :1 --> n的最短路
d2[n]可以松弛其后继的次短路(和最短路但不会成功),d1[n]可以松弛其后继的最短路和次短路;
做法:松弛时 1:对于v点最短路成功松弛后,再用v点最短路被松弛前的距离松弛v点次短路
2:对于无法松弛v点最短路时,尝试松弛v点次短路(次短路的长度长于最短路!)
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<vector>
using namespace std;
typedef pair<int,int> pii;
#define MAXN 5050
int d1[MAXN],d2[MAXN];
vector<pii>vec[MAXN];
void Dijkstra()
{
priority_queue<pii,vector<pii>,greater<pii> >que;
memset(d1,0x3f,sizeof(d1));
memset(d2,0x3f,sizeof(d2));
d1[1] = 0;
que.push(pii(0,1));
while(!que.empty())
{
pii cur = que.top(); que.pop();
int u = cur.second;
if(d2[u] < cur.first)continue;
for(int i = 0;i < vec[u].size();i++)
{
pii tem = vec[u][i];
int d = cur.first + tem.second;
int v = tem.first;
if(d1[v] > d)
{
swap(d1[v],d);
que.push(pii(d1[v],v));
}
if(d2[v] > d && d > d1[v])
{
d2[v] = d;
que.push(pii(d2[v],v));
}
}
}
}
int main()
{
int n,m,w,u,v;
while(scanf("%d%d",&n,&m) != EOF)
{
for(int i = 1;i <= n;i++)vec[i].clear();
for(int i = 1;i <= m;i++)
{
scanf("%d%d%d",&u,&v,&w);
vec[u].push_back(pii(v,w));
vec[v].push_back(pii(u,w));
}
Dijkstra();
printf("%d\n",d2[n]);
}
}