比较显然的,题干问的是第k+1长的路最短;
那么二分答案是正确的方向;
但是怎么验证?
我们可以将所有边权大于二分的答案的边视为边权是1,否则看成0;
然后从1~n跑最短路,如果答案大于二分的答案那么就不成立,否则成立;
这种思维比较重要,代码还是很简单的;
#include <bits/stdc++.h> using namespace std; int head[2000010],cnt; class littlestar{ public: int to; int nxt; int w; void add(int u,int v,int gg){ nxt=head[u]; to=v; w=gg; head[u]=cnt; } }star[2000010]; int n,p,k; int dis[100010],vis[100010]; bool SPFA(int x) { queue<int> q; memset(dis,0x3f,sizeof(dis)); dis[1]=0; memset(vis,0,sizeof(vis)); q.push(1); while(q.size()){ int u=q.front(); q.pop(); vis[u]=0; for(int i=head[u];i;i=star[i].nxt){ int v=star[i].to; if(dis[v]>dis[u]+(star[i].w>x)){ dis[v]=dis[u]+(star[i].w>x); if(!vis[v]){ vis[v]=1; q.push(v); } } } } if(dis[n]<=k) return 1; else{ return 0; } } int main() { cin>>n>>p>>k; for(int i=1;i<=p;i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); star[++cnt].add(u,v,w); star[++cnt].add(v,u,w); } int l=0,r=1000000; while(l<r){ int mid=(l+r)/2; if(SPFA(mid)){ r=mid; } else{ l=mid+1; } } if(l==1000000) l=-1; cout<<l<<endl; }