所谓次短路,就是又次又短的路
(逃)
解析
使用两遍swap是更新sec的好方法
一定要判断是严格次短才更新sec的答案!
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define il inline
const int N=200050;
inline ll read(){
ll x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
int n,m,k;
struct node{
int to,nxt,w;
}p[N<<1];
int fi[N],cnt;
inline void addline(int x,int y,int w){
p[++cnt]=(node){y,fi[x],w};fi[x]=cnt;
}
int du[N];
int mn[N],sec[N];
#define pr pair<int,int>
#define mkp make_pair
priority_queue<pr,vector<pr>,greater<pr> >q;
int num[N];
void dij(){
memset(mn,0x7f,sizeof(mn));memset(sec,0x7f,sizeof(sec));
mn[1]=0;q.push(mkp(0,1));
while(!q.empty()){
int now=q.top().second,w=q.top().first;q.pop();
if(w>sec[now]) continue;
num[now]++;
//printf("now=%d w=%d\n",now,w);
for(int i=fi[now];~i;i=p[i].nxt){
int to=p[i].to;
if(to!=1&&to!=n&&du[to]<k) continue;
int ww=w+p[i].w,flag=0;int qwq=ww;
//printf(" to=%d ww=%d mn=%d sec=%d\n",to,ww,mn[to],sec[to]);
if(ww<mn[to]){
swap(ww,mn[to]);flag=1;
}
if(ww!=mn[to]&&ww<sec[to]) swap(ww,sec[to]),flag=1;
if(flag) q.push(mkp(qwq,to));
//printf(" to=%d ww=%d mn=%d sec=%d\n",to,ww,mn[to],sec[to]);
}
}
return;
}
bool vis[5050][5050];
int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
memset(fi,-1,sizeof(fi));cnt=-1;
n=read();m=read();k=read();
for(int i=1;i<=m;i++){
int x=read(),y=read(),w=read();
if(!vis[x][y]&&x!=y){
du[x]++;du[y]++;
vis[x][y]=vis[y][x]=1;
}
addline(x,y,w);addline(y,x,w);
}
dij();
printf("%d\n",sec[n]<1e9?sec[n]:-1);
return 0;
}
/*
14 3 1 2
2 7 5 0
3 4 -10 1
9 10 1 0
*/