1. 程式人生 > >TYVJ1981——電話網路(二分答案)

TYVJ1981——電話網路(二分答案)

描述 由於地震使得連線汶川縣城電話線全部損壞,假如你是負責將電話線接到震中汶川縣城的負責人,汶川縣城周圍分佈著N(1<=N <=1,000)根按1…N順次編號的廢棄的電話線杆,任意兩根電話線杆間都沒有電話線相連。一共P(1<=P<=10,000)對電話線杆間可以拉電話線,其餘的那些由於地震使得電線杆已經倒塌而無法被連線。 第i對電話線杆的兩個端點分別為Ai、Bi,它們間的距離為Li (1<= Li <=1,000,000)。資料中保證每對(Ai,Bi)最多隻出現1次。編號為1的電話線杆已經接入了全國的電話網路,整個縣城的電話線全都連到了編號為N的電話線杆上。也就是說,你的任務僅僅是找一條將1號和N號電話線杆連起來的路徑,其餘的電話線杆並不一定要連入電話網路。 電信公司決定支援災區免費為汶川縣城連結K(0<=K<N)對由你指定的電話線杆。對於此外的那些電話線,需要為它們付費,等於其中最長的電話線的長度(每根電話線僅連結一對電話線杆)。如果需要連結的電話線杆不超過K對,那麼總支出為0。 請你計算一下,將電話線引到震中汶川縣城最少需要在電話線上花多少錢。 輸入 輸入檔案的第一行包含三個用空格隔開的整數:N,P和K; 第二行到第P+1行,每行分別都為三個用空格隔開的整數:Ai,Bi和Li。 輸出 輸出檔案中僅包含一個整數,表示在這項工程上的最小支出。如果任務不可能完成,則輸出-1。 樣例輸入 5 7 1 1 2 5 3 1 4 2 4 8 3 2 3 5 2 9 3 4 7 4 5 6 樣例輸出 4 提示 【樣例解釋】 選擇如下的連結方案:1->3;3->2;2->5,這3對電話線杆間需要的電話線的長度分別為4、3、9。FJ讓電信公司提供那條長度為9的電話線,於是,他所需要購買的電話線的最大長度為4。 資料規模】 對於40%的資料,保證有n<=200: 對於100%的資料,保證有n<=1000。

本來以為是最小生成樹

結果發現做不了

正解是二分答案

二分一個最大的代價

那麼對於每一條路徑,如果其長度大於了二分的代價

那麼也就是說要用一次免費的

就把其長度設為1

否則為0

最後看距離是否大於k

#include<bits/stdc++.h>
using namespace std;
inline int read(){
	char ch=getchar();
	int res=0;
	while(!isdigit(ch)) ch=getchar();
	while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48),ch=
getchar(); return res; } int n,p,k,cnt,l,ans,r,adj[1005],nxt[20005],to[20005],val[20005],cost[20005],dis[1005]; bool vis[1005]; inline void addedge(int u,int v,int w){ nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v,val[cnt]=w; nxt[++cnt]=adj[v],adj[v]=cnt,to[cnt]=u,val[cnt]=w; } inline int check(int x){ int q[200005],qn; memset
(dis,127/3,sizeof(dis)); memset(vis,false,sizeof(vis)); q[qn=1]=1,vis[1]=true,dis[1]=0; for(int ql=1;ql<=qn;ql++){ int u=q[ql]; for(int e=adj[u];e;e=nxt[e]){ int v=to[e]; int c=val[e]<=x?0:1; if(dis[u]+c<dis[v]) { dis[v]=dis[u]+c; if(!vis[v]){ vis[v]=true; q[++qn]=v; } } } vis[u]=false; } if(dis[n]>p) { return 100; } return dis[n]<=k; } int main(){ r=0,l=0; n=read(),p=read(),k=read(); for(int i=1;i<=p;i++){ int u=read(),v=read(),w=read(); addedge(u,v,w); r=max(r,w); } while(l<r){ int mid=(l+r)>>1; int u=check(mid); if(u==1) r=mid; else if(u==0)l=mid+1; else { cout<<"-1"<<'\n'; return 0; } } cout<<l<<'\n'; }