Luogu P1948 [USACO08JAN]Telephone Lines
题目
两眼题
二分一个\(lim\),然后跑最短路(边权\(\le lim\)的边长度为\(0\),\(>lim\)的长度为\(1\)),然后判断\(dis_{1,n}\le k\)。
#include<bits/stdc++.h>
#define pi pair<int,int>
#define pb push_back
using namespace std;
int read(){int x;scanf("%d",&x);return x;}
const int N=1001,M=10001;
vector<pi>E[N];
int n,m,k,dis[N],vis[N];priority_queue<pi,vector<pi>,greater<pi>>q;
void dfs(int u){vis[u]=1;for(auto [v,w]:E[u])if(!vis[v])dfs(v);}
int check(int lim)
{
memset(dis,0x3f,sizeof dis),memset(vis,0,sizeof vis),q.push(pi(dis[1]=0,1));
while(!q.empty())
{
int u=q.top().second,w;q.pop();if(vis[u])continue;vis[u]=1;
for(auto[v,x]:E[u])if(dis[u]+(w=x>lim)<dis[v])dis[v]=dis[u]+w,q.push(pi(dis[v],v));
}
return dis[n]<=k;
}
int main()
{
n=read(),m=read(),k=read();
for(int i=1,u,v,w;i<=m;++i)u=read(),v=read(),w=read(),E[u].pb(pi(v,w)),E[v].pb(pi(u,w));
dfs(1);
if(!vis[n]) return !printf("-1");
int l=0,r=1e6,mid;
while(l<=r) mid=l+r>>1,check(mid)? r=mid-1:l=mid+1;
printf("%d",l);
}