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);
}
posted @ 2019-11-11 22:26  Shiina_Mashiro  阅读(71)  评论(0编辑  收藏  举报