问题:
某街区共有R条道路、N个路口。道路可以双向通行。问1号路口到N号路口的次短路的长度是多少?次短路指的是比最短路长度长的次短路径。同一条边可以经过多次。
限制条件
1⩽N⩽5000
1⩽R⩽100000
输入示例:
N=4
R=4
1 2 100 //1 2表示节点,100表示1、2之间距离
2 4 200
2 3 250
3 4 100
输出示例:
450
Dijkstra算法:
//#include <bits/stdc++.h>
#include <iostream>
#include <queue>
#include <cstring>
#include <cstdlib>
const int MAX = 999999;
const int INF = 0x7fffffff;
using namespace std;
struct Edge{
int num,len;
bool operator <(const Edge &a)const{
return a.len < len;
}
};
int u[MAX],v[MAX],w[MAX],
dis[MAX],second[MAX],
first[MAX / 4],next[MAX], //必须除以4
n,r;
void dijkstra()
{
priority_queue<Edge> que;
dis[0] = 0;
second[0] = INF;
for(int i = 0; i < n; i++)
{
dis[i] = INF;
second[i] = INF;
}
Edge temp;
temp.len = 0;
temp.num = 0;
que.push(temp);
while(!que.empty())
{
Edge head = que.top();
que.pop();
if(head.len > second[head.num]) continue;
int k = first[head.num];
while(k != -1)
{
int d = head.len + w[k];
if(dis[v[k]] > d)
{
swap(dis[v[k]], d);
temp.len = dis[v[k]];
temp.num = v[k];
que.push(temp);
}
if(dis[v[k]] < d && second[v[k]] > d)
{
second[v[k]] = d;
temp.len = second[v[k]];
temp.num = v[k];
que.push(temp);
}
k = next[k];
}
}
}
int main()
{
cin>>n>>r;
memset(first, -1, sizeof(first)); //不能拿fill()
for(int i = 0; i < r; i++)
{
cin>>u[i]>>v[i]>>w[i];
u[i]--;
v[i]--;
next[i] = first[u[i]];
first[u[i]] = i;
u[i + r] = v[i];
v[i + r] = u[i];
w[i + r] = w[i];
next[i + r] = first[u[i + r]];
first[u[i + r]] = i + r;
}
dijkstra();
cout<<second[n - 1]<<endl;
return 0;
}