所谓次短路,就是又次又短的路
(逃)
解析
使用两遍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_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);#endifmemset(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 22 7 5 03 4 -10 19 10 1 0
*/