Telephone Lines [POJ3662] [二分答案]
Description
Farmer John打算将电话线引到自己的农场,但电信公司并不打算为他提供免费服务。于是,FJ必须为此向电信公司支付一定的费用。 FJ的农场周围分布着N(1 <= N <= 1,000)根按1..N顺次编号的废弃的电话线杆,任意两根电话线杆间都没有电话线相连。一共P(1 <= P <= 10,000)对电话线杆间可以拉电话线,其余的那些由于隔得太远而无法被连接。
第i对电话线杆的两个端点分别为A_i、B_i,它们间的距离为Li (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
Sample Output
4
Hint
输入说明:
一共有5根废弃的电话线杆。电话线杆1不能直接与电话线杆4、5相连。电话线杆5不能直接与电话线杆1、3相连。其余所有电话线杆间均可拉电话线。电信公司可以免费为FJ连结一对电话线杆。
输出说明:
FJ选择如下的连结方案:1->3;3->2;2->5,这3对电话线杆间需要的电话线的长度分别为4、3、9。FJ让电信公司提供那条长度为9的电话线,于是,他所需要购买的电话线的最大长度为4。
Analysis
我们二分一个k+1的大小lim,统计最少需要用到大于lim的路的条数,在k以内就够
如何统计最少需要用多少条大于lim的路?
把每一条大于lim的路权值看作1,跑最短路即可。
Code
- #include<set>
- #include<map>
- #include<queue>
- #include<stack>
- #include<cmath>
- #include<cstdio>
- #include<cstring>
- #include<iostream>
- #include<algorithm>
- #define RG register int
- #define rep(i,a,b) for(RG i=a;i<=b;++i)
- #define per(i,a,b) for(RG i=a;i>=b;--i)
- #define ll long long
- #define inf (1<<29)
- #define maxn 1005
- #define maxm 10005
- #define add(x,y,z) e[++cnt]=(E){y,head[x],z},head[x]=cnt
- using namespace std;
- int n,m,k,cnt;
- int dis[maxn],vis[maxn],head[maxn];
- struct E{
- int v,next,val;
- }e[maxm<<];
- inline int read()
- {
- int x=,f=;char c=getchar();
- while(c<''||c>''){if(c=='-')f=-;c=getchar();}
- while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
- return x*f;
- }
- int check(int lim)
- {
- queue<int> que;que.push();
- memset(dis,,sizeof(dis));dis[]=;
- RG u,v,d;
- while(!que.empty())
- {
- u=que.front(),que.pop(),vis[u]=;
- for(RG i=head[u];i;i=e[i].next)
- {
- v=e[i].v,d=e[i].val>lim?:;
- if(dis[v]>dis[u]+d)
- {
- dis[v]=dis[u]+d;
- if(!vis[v]) vis[v]=,que.push(v);
- }
- }
- }
- return dis[n]<=k;
- }
- int main()
- {
- n=read(),m=read(),k=read();
- for(RG i=,a,b,c;i<=m;i++)
- {
- a=read(),b=read(),c=read();
- add(a,b,c),add(b,a,c);
- }
- int l=,r=,ans=-,mid;
- while(l<=r)
- {
- mid=l+r>>;
- if(check(mid)) ans=mid,r=mid-;
- else l=mid+;
- }
- cout<<ans;
- return ;
- }
Telephone Lines [POJ3662] [二分答案]的更多相关文章
- 【POJ3662】Telephone Lines dij + 二分答案
题目大意:给定一个 N 个顶点,M 条边的无向图,求一条从 1 号节点到 N 号节点之间的路径,使得第 K+1 大的边权最小,若 1 与 N 不连通,输出 -1. 最小化最大值一类的问题,采用二分答案 ...
- POJ3662 [USACO08JAN]Telephone Lines (二分答案/分层图求最短路)
这道题目有两种解法: 1.将每个点视为一个二元组(x,p),表示从起点到x有p条路径免费,相当于构建了一张分层图,N*k个节点,P*k条边.在这张图上用优先队列优化的SPFA算法求解,注意这里的d数组 ...
- POJ 3662 Telephone Lines(二分答案+SPFA)
[题目链接] http://poj.org/problem?id=3662 [题目大意] 给出点,给出两点之间连线的长度,有k次免费连线, 要求从起点连到终点,所用的费用为免费连线外的最长的长度. 求 ...
- POJ 3662 Telephone Lines【二分答案+最短路】||【双端队列BFS】
<题目链接> 题目大意: 在一个节点标号为1~n的无向图中,求出一条1~n的路径,使得路径上的第K+1条边的边权最小. 解题分析:直接考虑情况比较多,所以我们采用二分答案,先二分枚举第K+ ...
- P1948 [USACO08JAN]电话线Telephone Lines(二分答案+最短路)
思路 考虑题目要求求出最小的第k+1大的边权,想到二分答案 然后二分第k+1大的边权wx 把所有边权<=wx的边权变为0,边权>wx的边权变为0,找出最短路之后,如果dis[T]<= ...
- POJ3662 Telephone Lines( dijkstral + 二分 )
POJ3662 Telephone Lines 题目大意:要在顶点1到顶点n之间建一条路径,假设这条路径有m条边,其中有k条边是免费的,剩余m-k条边是要收费的, 求这m-k条边中花费最大的一条边的最 ...
- POJ - 3662 Telephone Lines (Dijkstra+二分)
题意:一张带权无向图中,有K条边可以免费修建.现在要修建一条从点1到点N的路,费用是除掉免费的K条边外,权值最大的那条边的值,求最小花费. 分析:假设存在一个临界值X,小于X的边全部免费,那么此时由大 ...
- POJ 3662 Telephone Lines (二分 + 最短路)
Farmer John wants to set up a telephone line at his farm. Unfortunately, the phone company is uncoop ...
- poj3662 Telephone Lines【最短路】【二分】
http://poj.org/problem?id=3662 Telephone Lines Time Limit: 1000MS Memory Limit: 65536K Total Submi ...
随机推荐
- 2019南昌邀请赛网络预选赛 I. Max answer(单调栈+暴力??)
传送门 题意: 给你你一序列 a,共 n 个元素,求最大的F(l,r): F(l,r) = (a[l]+a[l+1]+.....+a[r])*min(l,r); ([l,r]的区间和*区间最小值,F( ...
- 20175209 《Java程序设计》第二周学习总结
教材学习内容总结 二三章介绍的主要是Java中的基本知识:数据类型及转换,数据的输入输出,数组,运算符表达式,和常见的一些语句,这些都是帮助我们学习Java的基本知识,而这些知识很大一部分都和C语言相 ...
- Web请求相关
HTTP简介 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送 ...
- 迭代器模式-Iterator(Java实现)
迭代器模式-Iterator 用于访问一个集合中的各个元素, 而又不会暴露集合的内部的细节. 本文展示的例子就是, 在猫群组里, 用迭代器遍历每一只猫. 本文章的例子的继承关系图如下: 其中: Cat ...
- 第十三节: EF的三种模式(三) 之 来自数据库的CodeFirst模式
一. 简介 [来自数据库的Code First模式]实质上并不是CodeFirst模式,而是DBFirst模式的轻量级版本,在该模式中取消了edmx模型和T4模板,直接生成了EF上下文和相应的类,该模 ...
- mongoose 连接数据库操作
连接数据库 var mongoose = require('mongoose'); var schema = mongoose.Schema; // 连接MongoDB mongoose.connec ...
- C++的一些小Tip
string转数字: 一种是转换为char*后再使用atoi:atoi(s.c_str()).这个方法的神奇之处在于,如果s是负数也能顺利转化,但是,在leetcode显示,自己先判断是不是负数的话计 ...
- Set集合判断对象重复的方法
Set<User> userSet = new HashSet<>(); User user1= new User("aa","11") ...
- 51nod--1072 威佐夫游戏 (博弈论)
题目: 1072 威佐夫游戏 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 有2堆石子.A B两个人轮流拿,A先拿.每次可以从一堆中取任意个或从2堆中取相同 ...
- linux各文件夹含义和作用
原文链接:https://blog.csdn.net/okyoung188/article/details/76315774 1.linux下各文件夹的意义: /bin:是binary的缩写, ...