#二分,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;
} 
posted @ 2020-08-12 15:22  lemondinosaur  阅读(84)  评论(0编辑  收藏  举报