zoukankan      html  css  js  c++  java
  • [洛谷] P1948 [USACO08JAN]Telephone Lines S(二分+SPFA)

    题面:

    P1948 [USACO08JAN]Telephone Lines S

    思路:

    贪心的想,如果一条简单路径中,把免费的K段都给了权值最大的K条边,那么第K+1条边肯定是最优的

    考虑二分答案,SPFA维护到$n$点的花费免费路线最少的路线,如果这个当前选取的边大于当前所二分判断的长度$x$,那么$dis[to]=dis[cur]+1$,否则$dis[to]=dis[cur]$,最后再判断$dis[n] leq k$是否成立。

     

    代码:

     1 #include <bits/stdc++.h>
     2 
     3 #define debug(...)  fprintf(stderr,__VA_ARGS__)
     4 #define DEBUG printf("Passing [%s] in LINE %d
    ",__FUNCTION__,__LINE__)
     5 #define Debug debug("Passing [%s] in LINE %d
    ",__FUNCTION__,__LINE__)
     6 #define rep(i,x,y) for(int i=(x);i<=(y);++i)
     7 
     8 using namespace std;
     9 typedef long long ll;
    10 typedef unsigned long long ull;
    11 typedef pair<int,int> pii;
    12 typedef pair<ll,int> pli;
    13 typedef pair<int,ll> pil;
    14 typedef pair<ll,ll> pll;
    15 
    16 const ll MOD=1e9+7;
    17 const int INF=0x3f3f3f3f;
    18 const int MAXN=1010;
    19 ll qpow(ll a,ll b){ll ret=1;for(;b;b>>=1) if(b&1) ret=ret*a%MOD,a=a*a%MOD;return ret;}
    20 
    21 int n,p,k;
    22 
    23 vector<pii> g[MAXN];
    24 int dis[MAXN],inq[MAXN];
    25 
    26 
    27 bool chk(int val){
    28     queue<int> q;
    29     memset(dis,0x3f,sizeof(dis));
    30     dis[1]=0;
    31     q.push(1);
    32     inq[1]=1;
    33     while(!q.empty()){
    34         int u=q.front();
    35         q.pop();
    36         inq[u]=0;
    37         for(int i=0;i<g[u].size();++i){
    38             int to=g[u][i].second,v=g[u][i].first;
    39             int s;
    40             if(v>val) s=dis[u]+1;
    41             else s=dis[u];
    42             if(dis[to]>s){
    43                 dis[to]=s;
    44                 if(!inq[to]){
    45                     inq[to]=1;
    46                     q.push(to);
    47                 }
    48             }
    49             
    50         }
    51     }
    52     if(dis[n]<=k) return 1;
    53     return 0;
    54 }
    55 
    56 
    57 int main(){
    58     cin>>n>>p>>k;
    59     int u,v,w;
    60     int r=0;
    61     rep(i,1,p)  scanf("%d%d%d",&u,&v,&w),g[u].push_back({w,v}),g[v].push_back({w,u}),r=max(r,w);
    62     int l=0;
    63     int fl=0;
    64     while(l<r){
    65         int mid=(l+r)>>1;
    66         if(chk(mid))    r=mid,fl=1;
    67         else l=mid+1;
    68     }
    69     if(!fl){
    70         cout<<"-1";
    71         return 0;
    72     }
    73     cout<<l;
    74     return 0;
    75 }
    View Code
  • 相关阅读:
    Linux Home目录硬盘空间缩减
    test
    ORACLE 数据泵 expdp/impdp
    mysql利用mysqlbinlog命令恢复误删除数据
    LogMiner日志挖掘分析管理
    Oracle 审计测试与总结
    redis 5.0.3 讲解、集群搭建
    联想服务器配置 RAID
    Cenots7对lvm逻辑卷分区大小的调整
    kvm 基本运维命令
  • 原文地址:https://www.cnblogs.com/JNzH/p/14038529.html
Copyright © 2011-2022 走看看