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 }

 

posted @ 2017-06-27 20:42  MJT12044  阅读(481)  评论(0编辑  收藏  举报