bzoj 1614 架设电话线

Description

FarmerJohn打算将电话线引到自己的农场,但电信公司并不打算为他提供免费服务。于是,FJ必须为此向电信公司
支付一定的费用。FJ的农场周围分布着N(1<=N<=1,000)根按1..N顺次编号的废弃的电话线杆,任意两根电话线杆间
都没有电话线相连。一共P(1<=P<=10,000)对电话线杆间可以拉电话线,其余的那些由于隔得太远而无法被连接。
第i对电话线杆的两个端点分别为A_i、B_i,它们间的距离为L_i(1<=L_i<=1,000,000)。数据中保证每对{A_i,B_i
}最多只出现1次。编号为1的电话线杆已经接入了全国的电话网络,整个农场的电话线全都连到了编号为N的电话线
杆上。也就是说,FJ的任务仅仅是找一条将1号和N号电话线杆连起来的路径,其余的电话线杆并不一定要连入电话
网络。经过谈判,电信公司最终同意免费为FJ连结K(0<=K<N)对由FJ指定的电话线杆。对于此外的那些电话线,FJ
需要为它们付的费用,等于其中最长的电话线的长度(每根电话线仅连结一对电话线杆)。如果需要连结的电话线
杆不超过K对,那么FJ的总支出为0。请你计算一下,FJ最少需要在电话线上花多少钱。

Input

* 第1行: 3个用空格隔开的整数:N,P,以及K
* 第2..P+1行: 第i+1行为3个用空格隔开的整数:A_i,B_i,L_i

Output

* 第1行: 输出1个整数,为FJ在这项工程上的最小支出。
如果任务不可能完成, 输出-1

Sample Input

5 7 1
1 2 5
3 1 4
2 4 8
3 2 3
5 2 9
3 4 7
4 5 6
输入说明:
一共有5根废弃的电话线杆。电话线杆1不能直接与电话线杆4、5相连。电话
线杆5不能直接与电话线杆1、3相连。其余所有电话线杆间均可拉电话线。电信
公司可以免费为FJ连结一对电话线杆。

Sample Output

4
输出说明:
FJ选择如下的连结方案:1->3;3->2;2->5,这3对电话线杆间需要的
电话线的长度分别为4、3、9。FJ让电信公司提供那条长度为9的电话线,于是,
他所需要购买的电话线的最大长度为4。
思路: 二分枚举答案+ 最短路径
 
 
 1 #include<bits/stdc++.h>
 2 using namespace std;  
 3 #define R register int 
 4 #define rep(i,a,b) for(R i=a;i<=b;i++) 
 5 #define Rep(i,a,b) for(R i=a;i>=b;i--) 
 6 #define rp(i,x)    for(R i=H[x];i!=-1;i=E[i].nt) 
 7 #define ms(i,a)    memset(a,i,sizeof(a))
 8 #define gc()       getchar()
 9 template<class T>void read(T &x){
10     x=0; char c=0;  
11     while (!isdigit(c)) c=gc(); 
12     while (isdigit(c)) x=x*10+(c^48),c=gc();  
13 }
14 int const N=1003; 
15 int const M=10003;   
16 int const inf=100000000;  
17 struct Edge{
18     int to,nt,w;  
19 }E[M<<1];  
20 int n,m,f[N],k,H[N],cnt,q[N*N],vis[N],dist[N];  
21 
22 void add(int a,int b,int c){
23     E[cnt]=(Edge){b,H[a],c}; H[a]=cnt++;  
24 }
25 int spfa(int mid){
26     ms(0,vis); rep(i,1,n)  dist[i]=inf;  
27     int cl=1; vis[1]=1;q[0]=1;  dist[1]=0;  
28     rep(i,0,cl-1){
29         int x=q[i];  
30         vis[x]=0;  
31         rp(i,x){
32             int v=E[i].to;  
33             int c=E[i].w>mid;  
34             if(dist[v]>dist[x]+c){
35                 dist[v]=dist[x]+c;  
36                 if(!vis[v]) vis[v]=1,q[cl++]=v;   
37             }
38         }
39     }
40     return dist[n];  
41 }
42 
43 int main(){
44     read(n); read(m); read(k);  
45     ms(-1,H);  
46     while (m--){
47         int x,y,z; read(x); read(y); read(z);  
48         add(x,y,z); add(y,x,z); 
49     }
50     int l=0,r=1000001;  
51     while (l<r){
52         int mid=(l+r)>>1; 
53         if(spfa(mid)<=k) r=mid; 
54         else l=mid+1; 
55     }
56     if(l==1000001) l=-1; 
57     printf("%d\n",l); 
58     return 0; 
59 
60 }
View Code

 

 

posted @ 2019-01-11 15:29  zjxxcn  阅读(156)  评论(0编辑  收藏  举报