分析:百度翻译一下题目发现是道求最短路且可以重复经过某点的情况,可以用Dijkstra求,具体做法:用 dist1[] 记录最短路,dist2[] 记录次短路。然后还是 spfa, 更新的时候分情况判断一下,次短路可能更新次短路,最短路可能更新次短路和最短路。。。记的更新完后把dist2[]也要加进去。
#include<iostream>
#include<cstring>
#include<set>
using namespace std;
const int maxn=5010;
const int maxm=400010;
const int inf=0x3f3f;
int n,m;
int p[maxn],eid,pre[maxn];
struct edge{
int v,next,w;
}e[maxm];
void init(){
memset(p,-1,sizeof(p));
eid=0;
}
void insert(int u,int v,int w){
e[eid].v=v;
e[eid].next=p[u];
e[eid].w=w;
p[u]=eid++;
}
void insert2(int u,int v,int w){
insert(u,v,w);
insert(v,u,w);
}
typedef pair<int,int>PII;
set<PII>min_heap;
int dist[maxn],dist2[maxn];
bool vst[maxn];
bool dijkstra(int v){
memset(vst,0,sizeof(vst));
memset(dist,0x3f,sizeof(dist));
memset(dist2,0x3f,sizeof(dist2));
dist[v]=0;
min_heap.insert(make_pair(0,v));
for(int i=0;i<2*n;i++)
{
if(min_heap.size()==0)return false;
set<PII>::iterator iter=min_heap.begin();
int j=iter->second;
min_heap.erase(*iter);
vst[j]=true;
for(int x=p[j];x!=-1;x=e[x].next){
int f=e[x].v;
if(dist[j]+e[x].w>dist[f]&&dist[j]+e[x].w<dist2[f]){
min_heap.erase(make_pair(dist2[f],f));
dist2[f]=dist[j]+e[x].w;
min_heap.insert(make_pair(dist2[f],f));
}
if(dist2[j]+e[x].w<dist2[f]){
min_heap.erase(make_pair(dist2[f],f));
dist2[f]=dist2[j]+e[x].w;
min_heap.insert(make_pair(dist2[f],f));
}
if(!vst[f]&&dist[j]+e[x].w<dist[f]){
min_heap.erase(make_pair(dist[f],f));
dist[f]=dist[j]+e[x].w;
min_heap.insert(make_pair(dist[f],f));
}
}
}
return true;
}
int main(){
init();
cin>>n>>m;
for(int i=0;i<m;i++){
int a,b,c;
cin>>a>>b>>c;
insert2(a,b,c);
}
dijkstra(1);
cout<<dist2[n]<<endl;
}