zoukankan      html  css  js  c++  java
  • 【Luogu】P1948电话线(二分SPFA)

      题目链接

      二分最长的电话线长度。把所有大于这个长度的边权设成1,小于等于的设成零,然后跑SPFA看dis[n]是否>k。若>k则l=mid+1

      否则r=mid-1

      放代码

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<algorithm>
    inline long long read(){
        long long num=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')    f=-1;
            ch=getchar();
        }
        while(isdigit(ch)){
            num=num*10+ch-'0';
            ch=getchar();
        }
        return num*f;
    }
    
    struct Edge{
        int next,to,dis;
    }edge[1000010];
    int head[100100],num;
    inline void add(int from,int to,int dis){
        edge[++num]=(Edge){head[from],to,dis};
        head[from]=num;
    }
    
    int val[100010];
    int f[1000001],h,t=1;
    bool vis[100010];
    int dis[100010];
    int ans;
    
    int main(){
        int n=read(),m=read(),k=read();
        for(int i=1;i<=m;++i){
            int from=read(),to=read(),dst=read();
            add(from,to,dst);
            add(to,from,dst);
            val[i]=dst;
        }
        std::sort(val+1,val+m+1);
        int l=1,r=m;
        
        while(l<=r){
            int mid=(l+r)>>1;
            int cost=val[mid];
            memset(vis,0,sizeof(vis));
            memset(dis,127/3,sizeof(dis));
            f[1]=1;h=0;t=1;dis[1]=0;
            while(h++<t){
                int from=f[h];
                vis[from]=0;
                for(int i=head[from];i;i=edge[i].next){
                    int to=edge[i].to;
                    int c;
                    if(edge[i].dis<=cost)    c=0;
                    else                     c=1;
                    if(dis[to]>dis[from]+c){
                        dis[to]=dis[from]+c;
                        if(!vis[to]){
                            vis[to]=1;
                            f[++t]=to;
                        }
                    }
                }
            }
            if(dis[n]>k)    l=mid+1;
            else{
                ans=cost;
                r=mid-1;
            }
        }
        printf("%d",ans==0?-1:ans);
        return 0;
    }
  • 相关阅读:
    mysql复制那点事
    全排列问题
    56. Merge Interval
    2. Add Two Numbers
    20. Valid Parentheses
    121. Best Time to Buy and Sell Stock
    120. Triangle
    96. Unique Binary Search Trees
    91. Decode Ways
    72. Edit Distance
  • 原文地址:https://www.cnblogs.com/cellular-automaton/p/7566593.html
Copyright © 2011-2022 走看看