1. 程式人生 > >BZOJ——1614: [Usaco2007 Jan]Telephone Lines架設電話線

BZOJ——1614: [Usaco2007 Jan]Telephone Lines架設電話線

printf char 。。 discus 全國 rip har content 說明

Time Limit: 5 Sec Memory Limit: 64 MB
Submit: 1930 Solved: 823
[Submit][Status][Discuss]

Description

Farmer John打算將電話線引到自己的農場,但電信公司並不打算為他提供免費服務。於是,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。

HINT

Source

Silver

二分當前的最小代價,如果 u 連出去的一條邊權比代價高,就考慮公司報銷。。

 1 #include <cstdio>
 2 #include <queue>
 3 
 4
#define min(a,b) (a<b?a:b) 5 6 inline void read(int &x) 7 { 8 x=0; register char ch=getchar(); 9 for(; ch>9||ch<0; ) ch=getchar(); 10 for(; ch>=0&&ch<=9; ch=getchar()) x=x*10+ch-0; 11 } 12 const int M(10005); 13 const int N(1005); 14 int n,k,p; 15 int head[N],sumedge; 16 struct Edge { 17 int v,next,w; 18 Edge(int v=0,int next=0,int w=0):v(v),next(next),w(w){} 19 }edge[M<<1]; 20 inline void ins(int u,int v,int w) 21 { 22 edge[++sumedge]=Edge(v,head[u],w),head[u]=sumedge; 23 edge[++sumedge]=Edge(u,head[v],w),head[v]=sumedge; 24 } 25 26 bool inq[N]; 27 int dis[N]; 28 std::queue<int>que; 29 int L,R,Mid,ans=-1; 30 inline bool check(int lim) 31 { 32 for(int i=1; i<=n; ++i) 33 dis[i]=0x3f3f3f3f,inq[i]=0; 34 for(; !que.empty(); ) que.pop(); 35 int cnt=0; que.push(1); dis[1]=0; 36 for(int u,v; !que.empty(); ) 37 { 38 u=que.front(); que.pop(); inq[u]=0; 39 for(int i=head[u]; i; i=edge[i].next) 40 { 41 v=edge[i].v; 42 cnt=(edge[i].w>lim); 43 if(dis[v]>dis[u]+cnt) 44 { 45 dis[v]=dis[u]+cnt; 46 if(!inq[v]) inq[v]=1,que.push(v); 47 } 48 } 49 } 50 return dis[n]<=k; 51 } 52 53 int Presist() 54 { 55 read(n),read(p),read(k); 56 for(int u,v,w,i=1; i<=p; ++i) 57 read(u),read(v),read(w),ins(u,v,w),R=R>w?R:w;; 58 for(; L<=R; ) 59 { 60 Mid=L+R>>1; 61 if(check(Mid)) 62 { 63 ans=Mid; 64 R=Mid-1; 65 } 66 else L=Mid+1; 67 } 68 printf("%d\n",ans); 69 return 0; 70 } 71 72 int Aptal=Presist(); 73 int main(int argc,char**argv){;}

BZOJ——1614: [Usaco2007 Jan]Telephone Lines架設電話線