zoukankan      html  css  js  c++  java
  • LOJ 架设电话线 【二分 + spfa】

    LOJ  架设电话线

    题面见链接。。。

    题解:

    一般来说看到这总 第 k 大的 都往二分想想。

    这题其实蛮基础的。

    二分这第 k +1 大的边的权值,然后整个图的边比它大的权值为 1 ,比他小的权值为 0 。 最后跑一遍 spfa 求出整个图的最短路径,如果 <= K 则成立,可继续缩小范围,否则则只能增加范围。。。

    代码如下:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=4005;
     4 int n,p,k,x,y,z,nxt[N],to[N],hea[N],w[N],cnt=0;
     5 bool vis[N];
     6 int dis[N],q[N],h,t,ans;
     7 inline void add(int x,int y,int ww)
     8 {
     9     to[++cnt]=y; nxt[cnt]=hea[x]; hea[x]=cnt; w[cnt]=ww;
    10 }
    11 inline bool check(int mx)
    12 {
    13     memset(vis,0,sizeof(vis));
    14     memset(dis,60,sizeof(dis)); dis[1]=0; vis[1]=true;
    15     h=0,t=1; q[1]=1; 
    16     while (h<t)
    17     {
    18         int x=q[++h]; vis[x]=false;
    19         for (int i=hea[x]; i; i=nxt[i])
    20         {
    21             int u=to[i];
    22             if (dis[u]>dis[x]+(w[i]>mx))
    23             {
    24                 dis[u]=dis[x]+(w[i]>mx);
    25                 if (vis[u]) continue;
    26                 vis[u]=true; q[++t]=u;
    27             }
    28         }
    29     }
    30     if (dis[n]<=k) return true; else return false;
    31 }
    32 int main()
    33 {
    34     scanf("%d%d%d",&n,&p,&k);
    35     for (int i=1; i<=p; ++i)
    36     {
    37         scanf("%d%d%d",&x,&y,&z);
    38         add(x,y,z); add(y,x,z);
    39     }
    40     int l=0,r=1000000; ans=0x3f3f3f3f;
    41     while (l<=r)
    42     {
    43         int mid=(l+r)/2;
    44         if (check(mid)) ans=min(ans,mid),r=mid-1;
    45         else l=mid+1;
    46     }
    47     if (ans==0x3f3f3f3f) printf("-1
    "); else printf("%d
    ",ans);
    48     return 0;
    49 }
    View Code

    fighting fighting fighting

  • 相关阅读:
    买不到的数目
    逆波兰表达式
    颠倒的价牌
    排它平方数
    寒假作业
    搭积木
    网友年龄
    九宫重排
    格子刷油漆
    高僧斗法
  • 原文地址:https://www.cnblogs.com/Frank-King/p/9751472.html
Copyright © 2011-2022 走看看