洛谷P1462 通往奥格瑞玛的道路
时间:2019-08-29
本文章向大家介绍洛谷P1462 通往奥格瑞玛的道路,主要包括洛谷P1462 通往奥格瑞玛的道路使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题目分析
题目描述
在艾泽拉斯,有n个城市。编号为1,2,3,...,n。城市之间有m条双向的公路,连接着两个城市,从某个城市到另一个城市,会遭到联盟的攻击,进而损失一定的血量。每次经过一个城市,都会被收取一定的过路费(包括起点和终点)。路上并没有收费站。假设1为暴风城,n为奥格瑞玛,而他的血量最多为b,出发时他的血量是满的。歪嘴哦不希望花很多钱,他想知道,在可以到达奥格瑞玛的情况下,他所经过的所有城市中最多的一次收取的费用的最小值是多少。
分析过程
看到最大值最小,想到二分答案
考虑到答案在固定集合过路费(val)中,我们只需要保证该集合单调性并在其中二分即可
二分点权集合,每一次都会得到一个点权,这个点权将是路径上所有点点权的最大值
在整张图上寻找路径,但是因为我们得到了一个最大值,所以在寻找过程中不选超过二分值得点
寻找路径便是招最短路,因为我们要的不能死亡就是扣血尽量小
要是不致死,那么二分出的点权就是有效的,继续向下二分,缩小点权范围
不然的话,扩大点权范围
还有一个不同于别人的优化,能加快二分速度
我们初始点在1号,结束点在n号,这两个点是必须经过的,所以最小的点权必须要比这两个点权更大,所以就可以从这两个值中间的更大的那个值的排名作为二分的左端点,详见代码
#include<bits/stdc++.h>
#define re register
#define ll long long
using namespace std;
inline int read()
{
int k=1,sum=0;
char c=getchar();
for(;c<'0' || c>'9';c=getchar()) if(c=='-') k=-1;
for(;c>='0' && c<='9';c=getchar()) sum=sum*10+c-'0';
return sum*k;
}
int n,m,b;
struct Edge{
int to,nxt,w;
};
const int N=1e4+10,M=5e4+10;
const int inf=1000000000+10;
Edge edge[M<<1];
int rk=1;
int head[N],cnt;
int val[N],tp[N];
int dis[N];
bool vis[N];
inline void Add(int x,int y,int w){
edge[++cnt].to=y;edge[cnt].nxt=head[x];edge[cnt].w=w;head[x]=cnt;
}
struct New{
int u,d;
bool operator<(const New& qwq) const{
return d>qwq.d;
}
};
priority_queue<New> Q;
inline bool Check(int top){
memset(dis,0x3f3f3f3f,sizeof(dis));memset(vis,0,sizeof(vis));
dis[1]=0;
Q.push((New){1,0});
while(!Q.empty()){
New fr=Q.top();Q.pop();
if(vis[fr.u]) continue;
vis[fr.u]=1;
int x=fr.u;
for(re int i=head[x];i;i=edge[i].nxt){
int y=edge[i].to,z=edge[i].w;
if(val[y]>top) continue;
if(dis[y]>dis[x]+z)
dis[y]=dis[x]+z;
Q.push((New){y,dis[y]});
}
}
if(dis[n]<=b) return 1;else return 0;
}
int main()
{
//freopen("agrm.in","r",stdin);
n=read();m=read();b=read();int js;val[1]=read();js=val[1];tp[1]=val[1];
for(re int i=2;i<=n;++i) {
val[i]=read();tp[i]=val[i];
if(val[i]<js) ++rk; //进行点权排序
}
for(re int i=1;i<=m;++i){
int u=read(),v=read(),w=read();
Add(u,v,w),Add(v,u,w);
}
sort(tp+1,tp+1+n); // 保证单调性,开始二分
if(!Check(inf)) {
puts("AFK");
return 0;
}
int l=rk,r=n,ans;
int mid;
while(l<=r){
mid=(l+r)>>1;
bool pd=Check(tp[mid]);
if(pd) {
r=mid-1;ans=tp[mid];
}
else l=mid+1;
}
cout<<ans;
return 0;
}
原文地址:https://www.cnblogs.com/IcedMoon/p/11427914.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 院长智能部署Frp内网穿透---支持多系统
- dotnet OpenXML 元素 cNvPr NonVisual Drawing Properties 重复 id 标识处理
- Magicodes.IE之花式导出
- vue列表点击切换颜色
- JVM加载过程科普
- 我没学过计算机,是怎么接了四个私活还挣了两个 iPad 的?
- Helm安装Prometheus Operator
- 【每日一题】【vue2源码学习】vue如何检测数组的变化
- JavaScript 实现输入框内容一键复制(附上 Vue 3 实现方式)
- python 迭代器/iterator与生成器/generator的区别
- CSS 实现文本超出容器范围用省略号显示(单行+多行)
- ESP8266和ROS收发消息读取模拟量控制LED亮度
- 纯 CSS 实现下拉菜单尖角图标(实心+空心)
- 3分钟短文:书接上回,Laravel数据库迁移的那些个小技巧
- 解密 Docker 挂载文件,宿主机修改后容器里文件没有修改