本题是一道分层图的问题,这道题可以抽象出二分解法,因为我们知道,假如我们二分答案,那么就可以根据比答案大的个数来进行check
也就是我们要找的是刚好比答案大k条的最小值,其实这个最小值一定就是题目中的某条,除了两种特殊情况,1是全部都满不足条件,一个是全部满足条件
因此我们的二分区间是0-1e6+1.全部都是01的最短路可以通过双端队列广搜来做
#include<iostream> #include<cstring> #include<deque> using namespace std; const int N=1e5+10; int h[N],ne[N],e[N],w[N],idx; bool st[N]; int dis[N]; int n,p,k; void add(int a,int b,int c){ e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++; } bool check(int bound){ deque<int> q; memset(st,0,sizeof st); q.push_back(1); memset(dis,0x3f,sizeof dis); dis[1]=0; while(q.size()){ int t=q.front(); q.pop_front(); if(st[t]) continue; st[t]=1; int i; for(i=h[t];i!=-1;i=ne[i]){ int j=e[i]; int x=w[i]>bound; if(dis[j]>dis[t]+x){ dis[j]=dis[t]+x; if(!x){ q.push_front(j); } else q.push_back(j); } } } return dis[n]<=k; } int main(){ cin>>n>>p>>k; int i; memset(h,-1,sizeof h); for(i=1;i<=p;i++){ int a,b,c; cin>>a>>b>>c; add(a,b,c); add(b,a,c); } int l=0, r=1e6+1; while(l<r){ int mid=l+r>>1; if(check(mid)) r=mid; else l=mid+1; } if(r==1e6+1) cout<<"-1"<<endl; else cout<<r<<endl; return 0; }