[Usaco2007 Jan]Telephone Lines架设电话线
又遇到最大最小的问题,一看就是二分答案。
二分最短路径只为mid是否可能,之后跑一遍spfa就可以了,(似乎出题人没有卡。。。请勿学习本人)
判断最短路径是否小于等于mid即可。
其他都是基本操作,具体看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll ;
struct edge{
int to,next,v;
}e[20005];
int n,p,k,cnt,h[1005],dis[1005];
bool pd[1005];
queue <int> q ;
inline void add(int u,int v,int w){
e[++cnt].to=v;
e[cnt].v=w;
e[cnt].next=h[u];
h[u]=cnt;
}
inline bool check(int x){
memset(dis,0x3f,sizeof(dis));
int i,now,s;
dis[1]=0;pd[1]=1;
q.push(1) ;
while(!q.empty()){
now=q.front();q.pop();
i=h[now];
while(i){
if(e[i].v>x) s=dis[now]+1;
else s=dis[now];
if(s<dis[e[i].to]){
dis[e[i].to]=s;
if(!pd[e[i].to]){
q.push(e[i].to) ;
pd[e[i].to]=1;
}
}
i=e[i].next;
}
pd[now]=0;
}
if(dis[n]<=k) return 1;
return 0;
}
int main(){
scanf("%d%d%d",&n,&p,&k);
for(int i=1;i<=p;i++){
int u,v,w ;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
int ans=-1,l=0,r=1000000,mid;
while(l<=r){
mid=(l+r)>>1;
if(check(mid)){r=mid-1;ans=mid;}
else l=mid+1;
}
cout<<ans;
return 0;
}
加油ヾ(◍°∇°◍)ノ゙