#二分,spfa#洛谷 1948 [USACO08JAN] Telephone Lines S
分析
二分答案,设高于答案的边权为1,否则为0
然后如果最短路答案\(\leq k\)那么这个答案符合要求
代码
#include <cstdio>
#include <cctype>
#include <queue>
#include <cstring>
#include <algorithm>
#define rr register
using namespace std;
const int N=1011; struct node{int y,w,next;}e[N*20];
int dis[N],W[N*10],a[N*10],v[N],as[N],t,n,m,z,k=1;
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline bool check(int now){
for (rr int i=1;i<=m;++i)
e[i<<1].w=e[i<<1|1].w=W[i]>a[now];
rr queue<int>q; q.push(1),v[1]=1;
memset(dis,42,sizeof(dis)),dis[1]=0;
while (q.size()){
rr int x=q.front(); q.pop();
for (rr int i=as[x];i;i=e[i].next)
if (dis[e[i].y]>dis[x]+e[i].w){
dis[e[i].y]=dis[x]+e[i].w;
if (!v[e[i].y]) v[e[i].y]=1,q.push(e[i].y);
}
v[x]=0;
}
return dis[n]<=z;
}
signed main(){
n=iut(); m=iut(); z=iut();
for (rr int i=1;i<=m;++i){
rr int x=iut(),y=iut(); W[i]=a[i]=iut();
e[++k]=(node){y,0,as[x]},as[x]=k;
e[++k]=(node){x,0,as[y]},as[y]=k;
}
sort(a+1,a+1+m),t=unique(a+1,a+1+m)-a-1;
rr int l=0,r=t+1;
while (l<r){
rr int mid=(l+r)>>1;
if (check(mid)) r=mid;
else l=mid+1;
}
if (l==t+1) printf("-1");
else printf("%d",a[l]);
return 0;
}