[洛谷] 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\n",__FUNCTION__,__LINE__)
 5 #define Debug debug("Passing [%s] in LINE %d\n",__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

 

posted @ 2020-11-25 21:07  JNzH  阅读(102)  评论(1编辑  收藏  举报