[Usaco2007 Jan]Telephone Lines架设电话线

LG1948

BZOJ1614

又遇到最大最小的问题,一看就是二分答案。

二分最短路径只为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;
}

猜你喜欢

转载自blog.csdn.net/HQG_AC/article/details/81395167