AcWing340通信道路/ USACO2008 Telephone Line S
解题思路
首先可以得到一个很容易得到的贪心策略,将一条路径上最贵的(边权最大)的\(K\)条边删去,那么我们剩下的路径中最贵(边权最大)的路就是原本这条路径上帝\(K + 1\)大的路。
于是原问题就可以转化为:
求一张无向图中最大的一条路径中的第\(K+1\)大的边
这就启发我们枚举所有的路径。
可行吗?
显然是不可行的,这个路很多,但是我们可以反向思考
我们可以假定一个距离\(x\),然后看看这张图上是否存在一条路径,使它上面第\(K + 1\)大的边长度为\(x\),进一步的,我们可以转化成为在这张图中,是否存在\(K\)条边,任意一条边的权重\(W_{i}>x\)
这样我们的\(check\)函数似乎就呼之欲出了
check函数
这里的\(check\)我们判断一张图中是否有\(K\)条权重大于\(x\)的边,可以进行一下转换:
对于边权\(W_{i} > x\) 的边,设置权重\(w_{i} = 1\)(这是小w,不是原题给定权重)
反之设置权重\(w_{i} = 0\)
然后跑下这张图的最短路(\(从1到N\)),判断是否\(\le k\)即可
Dijkstra写法 \(O(mlog^{2}n)\)
这没什么好说的,就是建图跑最短路,因为边权非负(只能是\(0或1\))
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
typedef pair<int, int> PII;
const int N = 20020;
int h[N], e[N], w[N], ne[N], idx;
int dist[N], st[N], n, m, k;
void add(int a, int b, int c)
{
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++ ;
}
bool check(int x)
{
memset(dist, 0x3f, sizeof dist);
memset(st, 0, sizeof st);
priority_queue<PII, vector<PII>, greater<> > heap;
dist[1] = 0, heap.push({dist[1], 1});
while (heap.size())
{
auto t = heap.top().second; heap.pop();
if (st[t]) continue ;
st[t] = true ;
for (int i = h[t]; ~i; i = ne[i])
{
int j = e[i], W = (w[i] > x);
if (dist[j] > dist[t] + W)
{
dist[j] = dist[t] + W;
heap.push({dist[j], j});
}
}
}
return dist[n] <= k;
}
int main()
{
scanf("%d%d%d", &n, &m, &k);
memset(h, -1, sizeof h);
while (m -- )
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
add(u, v, w), add(v, u, w);
}
int l = 0, r = 1e6 + 1;
while (l < r)
{
int mid = l + r >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
if (r == 1e6 + 1) r = -1;
printf("%d\n", r);
return 0;
}
双端队列广搜 \(O(mlogn)\)
因为边权只有\(0-1\),可以用双端队列广搜,时间是线性的,再乘上二分次数,是\(O(mlogn)\)
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
typedef pair<int, int> PII;
const int N = 20020;
int h[N], e[N], w[N], ne[N], idx;
int dist[N], st[N], n, m, k;
void add(int a, int b, int c)
{
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++ ;
}
bool check(int x)
{
memset(dist, 0x3f, sizeof dist);
memset(st, 0, sizeof st);
deque<int> dq;
dist[1] = 0, dq.push_back(1);
while (dq.size())
{
int t = dq.front(); dq.pop_front();
if (st[t]) continue ;
st[t] = true ;
for (int i = h[t]; ~i; i = ne[i])
{
int j = e[i], W = (w[i] > x);
if (dist[j] > dist[t] + W)
{
dist[j] = dist[t] + W;
if (W) dq.push_back(j);
else dq.push_front(j);
}
}
}
return dist[n] <= k;
}
int main()
{
scanf("%d%d%d", &n, &m, &k);
memset(h, -1, sizeof h);
while (m -- )
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
add(u, v, w), add(v, u, w);
}
int l = 0, r = 1e6 + 1;
while (l < r)
{
int mid = l + r >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
if (r == 1e6 + 1) r = -1;
printf("%d\n", r);
return 0;
}
SPFA \(O(mlogn\sim 被卡飞)\)
和Dijkstra一样,跑个最短路
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
typedef pair<int, int> PII;
const int N = 20020;
int h[N], e[N], w[N], ne[N], idx;
int dist[N], st[N], n, m, k;
void add(int a, int b, int c)
{
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++ ;
}
bool check(int x)
{
memset(dist, 0x3f, sizeof dist);
memset(st, 0, sizeof st);
queue<int> q;
dist[1] = 0, q.push(1), st[1] = true;
while (q.size())
{
int t = q.front(); q.pop();
st[t] = false ;
for (int i = h[t]; ~i; i = ne[i])
{
int j = e[i], W = (w[i] > x);
if (dist[j] > dist[t] + W)
{
dist[j] = dist[t] + W;
if (!st[j]) q.push(j), st[j] = true ;
}
}
}
return dist[n] <= k;
}
int main()
{
scanf("%d%d%d", &n, &m, &k);
memset(h, -1, sizeof h);
while (m -- )
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
add(u, v, w), add(v, u, w);
}
int l = 0, r = 1e6 + 1;
while (l < r)
{
int mid = l + r >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
if (r == 1e6 + 1) r = -1;
printf("%d\n", r);
return 0;
}
关于时间
\(AcWing:Dijkstra\ 150ms,双端队列BFS\ \ 56ms,SPFA\ 63ms\)
\(Luogu:Dijkstra\ 238ms, 双端队列BFS\ 73ms, SPFA\ 89ms\)
Accepted!
AcWing340通信道路/ USACO2008 Telephone Line S的更多相关文章
- BZOJ1610: [Usaco2008 Feb]Line连线游戏
1610: [Usaco2008 Feb]Line连线游戏 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1301 Solved: 571[Submit ...
- BZOJ 1610: [Usaco2008 Feb]Line连线游戏
1610: [Usaco2008 Feb]Line连线游戏 Description Farmer John最近发明了一个游戏,来考验自命不凡的贝茜.游戏开始的时 候,FJ会给贝茜一块画着N (2 &l ...
- 1610: [Usaco2008 Feb]Line连线游戏
1610: [Usaco2008 Feb]Line连线游戏 Time Limit: 5 Sec Memory Limit: 64 MB Submit: 1396 Solved: 615 [Subm ...
- [bzoj1610][Usaco2008 Feb]Line连线游戏_暴力枚举
Line连线游戏 bzoj-1610 Usaco-2008 Feb 题目大意:Farmer John最近发明了一个游戏,来考验自命不凡的贝茜.游戏开始的时 候,FJ会给贝茜一块画着N (2 <= ...
- [Usaco2008 Feb]Line连线游戏[暴力][水题]
Description Farmer John最近发明了一个游戏,来考验自命不凡的贝茜.游戏开始的时 候,FJ会给贝茜一块画着N (2 <= N <= 200)个不重合的点的木板,其中第i ...
- 【BZOJ】1610: [Usaco2008 Feb]Line连线游戏(几何)
http://www.lydsy.com/JudgeOnline/problem.php?id=1610 两种做法,一种计算几何,一种解析几何,但是计算几何的复杂度远远搞出解析集合(虽然精度最高) 计 ...
- 【计算几何】【斜率】bzoj1610 [Usaco2008 Feb]Line连线游戏
枚举直线,计算斜率,排序,统计答案. #include<cstdio> #include<cmath> #include<algorithm> using name ...
- [BZOJ1610] [Usaco2008 Feb] Line连线游戏 (set)
Description Farmer John最近发明了一个游戏,来考验自命不凡的贝茜.游戏开始的时 候,FJ会给贝茜一块画着N (2 <= N <= 200)个不重合的点的木板,其中第i ...
- 【BZOJ】1610: [Usaco2008 Feb]Line连线游戏
[算法]计算几何 [题解]计算所有斜率排序去重. 实数判断相等用fabs(...)≤eps. ★斜率题一定要注意斜率不存在的情况!!! 其实我觉得这份代码可以hack的…… #include<c ...
- bzoj1610 [Usaco2008 Feb]Line连线游戏 几何+暴力
Description Farmer John最近发明了一个游戏,来考验自命不凡的贝茜.游戏开始的时 候,FJ会给贝茜一块画着N (2 <= N <= 200)个不重合的点的木板,其中第i ...
随机推荐
- 如何理解「数字化是 IT 公司在给传统企业贩卖焦虑」?
焦虑,不是IT公司贩卖给传统企业的!这个论断本身就不成立!数字化的动因是企业内部,生产中的七大浪费还不够么?数据不畅导致的决策失败还少吗?去问下企业业主,诸如此类的问题多了去了,数字化服务商只是来帮着 ...
- mysql 判断 字段为空 的一个小误区(又忘了)
今天判断mysql是否为空 直接写某字段 例 image_url !=null 结果数据库不报错误 并且没有返回相对数据. 又忘了这个事.今天特地记录一下. 因为null 表示什么也不是, 不能= ...
- iptables基本使用举例
一.链的基本操作 1.清除所有的规则. 1)清除预设表filter中所有规则链中的规则. # iptables -F 2)清除预设表filter中使用者自定链中的规则. #iptables -X #i ...
- 微光互联 TX800-U 扫码器无法输出中文到光标的问题
问题背景 某检测场有一批扫码器,购于微光互联,型号 TX800-U,用于在不同办理窗口间扫描纸质材料上的二维码,简化录入过程.扫码器通过 USB 接入 PC 系统 (windows),自动安装驱动,接 ...
- 1、使用简单工厂模式设计能够实现包含加法(+)、减法(-)、乘法(*)、除法(/)四种运算的计算机程序,要求输入两个数和运算符,得到运算结果。要求使用相关的工具绘制UML类图并严格按照类图的设计编写程
1.使用简单工厂模式设计能够实现包含加法(+).减法(-).乘法(*).除法(/)四种运算的计算机程序,要求输入两个数和运算符,得到运算结果.要求使用相关的工具绘制UML类图并严格按照类图的设计编写程 ...
- 虚拟机安装Linux系统的网络配置
1. 进入配置文件配置.如果不知道ifcfg 后的内容.使用ifconfig vi /etc/sysconfig/network-scripts/ifcfg-ens33 如果不知道网关怎样配置就找到这 ...
- 函数柯里化实现sum函数
需求 实现sum函数,使其可以传入不定长参数,以及不定次数调用 //示例 console.log(sum(1,2)(3)()) //6 console.log(sum(2,3,4,5)(1,2)(3) ...
- Spring 深入——IoC 容器 02
IoC容器的实现学习--02 目录 IoC容器的实现学习--02 回顾 IoC 容器的初始化过程: BeanDefinition 的 Resource 定位 小结: 回顾 前面学习了 IoC 模式的核 ...
- 如何使用python程序打包工具pyinstaller
**通过**```pythonpyinstaller -F demo.py```**即可把demo.py打包成可独立运行的demo.exe** **pyinstaller在cmd使用格式:***pyi ...
- 1.-Django项目结构
一.Django简介 Django是一个开放源代码的Web应用框架,由Python写成.采用了MTV的框架模式,即模型M,视图V和模版T. Django基本组件: 1.基本配置文件/路由系统 2. ...