Telephone Lines
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 5696   Accepted: 2071

Description

Farmer John wants to set up a telephone line at his farm. Unfortunately, the phone company is uncooperative, so he needs to pay for some of the cables required to connect his farm to the phone system.

There are N (1 ≤ N ≤ 1,000) forlorn telephone poles conveniently numbered 1..N that are scattered around Farmer John's property; no cables connect any them. A total of P (1 ≤ P ≤ 10,000) pairs of poles can be connected by a cable; the rest are too far apart.

The i-th cable can connect the two distinct poles Ai and Bi, with length Li (1 ≤ Li ≤ 1,000,000) units if used. The input data set never names any {Ai, Bi} pair more than once. Pole 1 is already connected to the phone system, and pole N is at the farm. Poles 1 and N need to be connected by a path of cables; the rest of the poles might be used or might not be used.

As it turns out, the phone company is willing to provide Farmer John with K (0 ≤ K < N) lengths of cable for free. Beyond that he will have to pay a price equal to the length of the longest remaining cable he requires (each pair of poles is connected with a separate cable), or 0 if he does not need any additional cables.

Determine the minimum amount that Farmer John must pay.

Input

* Line 1: Three space-separated integers: N, P, and K
* Lines 2..P+1: Line i+1 contains the three space-separated integers: Ai, Bi, and Li

Output

* Line 1: A single integer, the minimum amount Farmer John can pay. If it is impossible to connect the farm to the phone company, print -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

Source

题意:给你n个节点,p条路(不一定每个节点之间都有路),每条路都对应一定的花费,现在修路公司可以免费为你修k条路,求不是免费的路中花费最大的一条的花费;
 
错因:分析出了这道问题其实就是最小化第k+1个数,然后一直在往这个方向是上想,又知道求数组中第k大数只要>x的数量>=k的最大x+1,就好,
 
分析:这道题很典型啊,
 http://blog.163.com/boatswain%40126/blog/static/169396412201071784521862/  分析的很到位
想像一个单调的函数,就不难写二分了,不过最后要注意区间的开闭性会影响到左右端点的初始化

总结二分搜索的两句话:1:球数组中的第k小数,就是求<x的数量>=k的最小x-1;

2.求数组中的第k大数,就是求>=x的数量>=k的最大x

最后非常重要的是:这两个求出来的数在数组中一定是存在的。

这个总结几乎可以概括来这段时间做的所有题了

#include<cstdio>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include<map>
#include <algorithm>
#include <set>
using namespace std;
#define MM(a) memset(a,0,sizeof(a))
typedef long long LL;
typedef unsigned long long ULL;
const int mod = ;
const double eps = 1e-;
const int inf = 0x3f3f3f3f;
const double g = ;
int tu[][], tu2[][], d[], used[];
int n, p, k, f, t, c;
void init2(int mid)
{
memset(used, , sizeof(used));
for (int i = ; i <= n; i++)
for (int j = ; j <= n; j++)
if (tu[i][j] == inf)
tu2[i][j] = inf;
else if (tu[i][j] >mid)
tu2[i][j] = ;
else
tu2[i][j] = ;
for (int i = ; i <= n; i++)
d[i] = tu2[][i];
d[] = ; used[] = ;
}
int ok(int mid)
{
init2(mid);
while ()
{
int u = , minn = inf;
for (int i = ; i <= n; i++)
if (d[i]<minn&&!used[i])
{
minn = d[i];
u = i;
}
if (!u) break;
used[u] = ;
for (int i = ; i <= n; i++)
if (d[i]>d[u] + tu2[u][i] && !used[i])
d[i] = d[u] + tu2[u][i];
}
if (d[n] >= inf)
return -;
else return d[n] <= k;
}
void init1()
{
memset(tu, inf, sizeof(tu));
for (int i = ; i <= n; i++)
tu[i][i] = ;
}
int main()
{
while (~scanf("%d %d %d", &n, &p, &k))
{
int l=-, r = ;
init1();
for (int i = ; i <= p; i++)
{
scanf("%d %d %d", &f, &t, &c);
tu[f][t] = tu[t][f] = c;
if (c>r) r = c;
}
int flag = ;
while (r - l> && flag)
{
int mid = (l + r) >> ;
int w = ok(mid);
if (w == )
r = mid;
else if (w == )
l = mid;
else if (w == -)
{
printf("-1\n");
flag = ;
}
}
if (flag)
printf("%d\n", r);
}
return ;
}

  下面是第一次wa的代码:

#include<cstdio>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include<map>
#include <algorithm>
#include <set>
using namespace std;
#define MM(a) memset(a,0,sizeof(a))
typedef long long LL;
typedef unsigned long long ULL;
const int mod = ;
const double eps = 1e-;
const int inf = 0x3f3f3f3f;
const double g=;
int tu[][],tu2[][],d[],used[];
int n,p,k,f,t,c;
int ok(int mid)
{
memset(tu2,inf,sizeof(tu2));
memset(d,inf,sizeof(d));
memset(used,,sizeof(used));
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(tu[i][j]!=inf)
if(tu[i][j]>mid)
tu2[i][j]=;
else
tu2[i][j]=;
d[]=;used[]=;
while()
{
int u=,minn=inf;
for(int i=;i<=n;i++)
if(d[i]<minn&&!used[i])
{
minn=d[i];
u=i;
}
if(!u)
break;
used[u]=;
for(int i=;i<=n;i++)
if(d[i]>d[u]+tu2[u][i]&&!used[i])
d[i]=d[u]+tu2[u][i];
}
return d[n]>=k;
}
int main()
{
while(~scanf("%d %d %d",&n,&p,&k))
{
int l=,r=;
memset(tu,inf,sizeof(tu));
for(int i=;i<=p;i++)
{
scanf("%d %d %d",&f,&t,&c);
tu[f][t]=tu[t][f]=c;
if(c>r) r=c;
}
r++;
while(r-l>)
{
int mid=(l+r)>>;
if(ok(mid))
l=mid;
else
r=mid;
}
printf("%d\n",l+);
}
return ;
}

poj 3662 Telephone Lines dijkstra+二分搜索的更多相关文章

  1. POJ - 3662 Telephone Lines (Dijkstra+二分)

    题意:一张带权无向图中,有K条边可以免费修建.现在要修建一条从点1到点N的路,费用是除掉免费的K条边外,权值最大的那条边的值,求最小花费. 分析:假设存在一个临界值X,小于X的边全部免费,那么此时由大 ...

  2. (poj 3662) Telephone Lines 最短路+二分

    题目链接:http://poj.org/problem?id=3662 Telephone Lines Time Limit: 1000MS   Memory Limit: 65536K Total ...

  3. POJ 3662 Telephone Lines【Dijkstra最短路+二分求解】

    Telephone Lines Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7214   Accepted: 2638 D ...

  4. poj 3662 Telephone Lines

    Telephone Lines Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7115   Accepted: 2603 D ...

  5. poj 3662 Telephone Lines(最短路+二分)

    Telephone Lines Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6973   Accepted: 2554 D ...

  6. poj 3662 Telephone Lines spfa算法灵活运用

    意甲冠军: 到n节点无向图,它要求从一个线1至n路径.你可以让他们在k无条,的最大值.如今要求花费的最小值. 思路: 这道题能够首先想到二分枚举路径上的最大值,我认为用spfa更简洁一些.spfa的本 ...

  7. POJ 3662 Telephone Lines (分层图)

    Telephone Lines Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6785   Accepted: 2498 D ...

  8. poj 3662 Telephone Lines(好题!!!二分搜索+dijkstra)

    Description Farmer John wants to set up a telephone line at his farm. Unfortunately, the phone compa ...

  9. POJ 3662 Telephone Lines (二分+Dijkstra: 最小化第k大的值)

    题意 Farmer John想从电话公司修一些电缆连接到他农场.已知N个电线杆编号为1,2,⋯N,其中1号已经连接电话公司,N号为农场,有P对电线杆可连接. 现给出P对电线杆距离Ai,Bi,Li表示A ...

随机推荐

  1. 自然语言处理工具pyhanlp分词与词性标注

    Pyhanlp分词与词性标注的相关内容记得此前是有分享过的.可能时间太久记不太清楚了.以下文章是分享自“baiziyu”所写(小部分内容有修改),供大家学习参考之用. 简介 pyhanlp是HanLP ...

  2. JavaScript中好用的对象数组去重

    对象数组去重 Demo数据如下: var items= [{ "specItems": [{ "id": "966480614728069122&qu ...

  3. 对C++类的继承和派生的理解

    C++中的继承是类与类之间的关系,是一个很简单很直观的概念,与现实世界中的继承类似,例如儿子继承父亲的财产. 1.继承(Inheritance)可以理解为一个类从另一个类获取成员变量和成员函数的过程. ...

  4. # 江西ccpc省赛-waves-(DP做法)

    江西ccpc省赛-waves-(DP做法) 题链:http://acm.hdu.edu.cn/showproblem.php?pid=6570 题意:给你长度为N,1≤N≤100000的一个数组,其中 ...

  5. opencv学习之读取图像-imread函数

    序 想要完整全面地学习opencv,仅凭阅读samples的示例源码是不够的.毕竟opencv是一个拥有非常多函数的程序库,所以在每学习一个函数时,芒果觉得有必要记录下来,分享给有需要的同学.于是,就 ...

  6. Sleepy Game CodeForces - 936B

    大意: 给定有向图, 初始点S, 两个人轮流移动, 谁不能移动则输, 但后手睡着了, 先手可以控制后手操作, 求最后先手结果. 刚开始看错了, 还以为后手也是最优策略.... 实际上判断是否有偶数个节 ...

  7. JavaScript冒泡排序法实现排序操作

    var arr = [10,8,6,9,1,7,1,13,5,1,9]; //冒泡排序 function bubbleSort(tmpArr){ for(var i = tmpArr.length-1 ...

  8. linux 之实现定时任务

    一.方式一 (1)命令行 的方法: 一.方式一 需求:每分钟执行一次/etc 目录的添加 到/tmp/a.txt 中 (1) touch a.txt创建文件 (2) crotab -e 进行任务的定制 ...

  9. Mac 常用软件

    command+space开启新的一天 窗口管理:Magnet 写代码:Pycharm.vscode.sublime text 虚拟机:VMware Fusion(买不起Parallels Deskt ...

  10. Jenkins+GitHub 项目环境搭建(一)

    安装Jenkins yum install -y java-1.8.0-openjdk wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkin ...