3336 /P1948电话网络(二分答案)
3336 电话网络
时间限制: 1 s
空间限制: 32000 KB
题目等级 : 黄金 Gold
题目描述 Description
由于地震使得连接汶川县城电话线全部损坏,假如你是负责将电话线接到震中汶川县城的负责人,汶川县城周围分布着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。
请你计算一下,将电话线引到震中汶川县城最少需要在电话线上花多少钱?
输入描述 Input Description
输入文件的第一行包含三个用空格隔开的整数:N,P和K。
第二行到第P+1行:每行分别都为空格隔开的整数:Ai,Bi和Li。
输出描述 Output Description
输出文件中仅包含一个整数,表示在这项工程上的最小支出。如果任务不可能完成,则输出-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
样例输出 Sample Output
4
数据范围及提示 Data Size & Hint
题目已有。
二分答案,落谷1948,codevs3336
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<queue> 5 using namespace std; 6 const int MAXN = 10010; 7 struct Edge{ 8 int to,w,nxt; 9 }e[20010]; 10 int head[MAXN],dis[MAXN]; 11 bool vis[MAXN]; 12 int n,m,k,cnt,ans=-1; 13 queue<int>q; 14 void add(int u,int v,int w) 15 { 16 ++cnt; 17 e[cnt].to = v; 18 e[cnt].w = w; 19 e[cnt].nxt = head[u]; 20 head[u] = cnt; 21 } 22 bool spfa(int x) //枚举花费的费用 23 { 24 memset(dis,0x3f,sizeof(dis)); 25 memset(vis,false,sizeof(vis)); 26 dis[1] = 0; 27 q.push(1); 28 vis[1] = true ; 29 while (!q.empty()) 30 { 31 int u = q.front(),c; 32 q.pop(); 33 for (int i=head[u]; i; i=e[i].nxt) 34 { 35 int v = e[i].to, w = e[i].w; 36 if (w<=x) c = 0; //如果小于x,这条道路不是最大费用,为0 37 else c = 1; //大于x,加上这条道路 38 if (dis[v]>dis[u]+c) 39 { 40 dis[v] = dis[u]+c; 41 if (!vis[v]) 42 { 43 q.push(v); 44 vis[v] = true; 45 } 46 } 47 } 48 vis[u] = false; 49 } 50 if (dis[n]>k) return false; 51 return true; 52 } 53 int main() 54 { 55 scanf("%d%d%d",&n,&m,&k); 56 int l = 1e9, r = 0; 57 for (int x,y,z,i=1; i<=m; ++i) 58 { 59 scanf("%d%d%d",&x,&y,&z); 60 l = min(l,z); 61 r = max(r,z); 62 add(x,y,z); 63 add(y,x,z); 64 } 65 while (l<=r) 66 { 67 int mid = (l+r)>>1; 68 if (spfa(mid)) 69 { 70 r = mid-1; 71 ans = mid; 72 } 73 else l = mid+1; 74 } 75 printf("%d",ans); 76 return 0; 77 }