洛谷P5304 [GXOI/GZOI2019] 旅行者
时间:2019-10-31
本文章向大家介绍洛谷P5304 [GXOI/GZOI2019] 旅行者,主要包括洛谷P5304 [GXOI/GZOI2019] 旅行者使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题意:给定一个n个点,m条边的有向图,有k个被标记的点,求这k个点中任意两个点之间的最短路径的最小值。
n<=100,000 m<=500,000
暴力的思路:对于每个被标记的点都跑一遍dij,然后在其它被标记的点中取min,复杂度 O(k*(n+m)logn)
对于暴力的优化:我们可以对这k个标记点进行二进制分组,分为两组,每次从set1向set2跑最短路取min,
再从set2向set1跑一遍最短路取min,因为若存在两个点之间的最短路为最小值,这两个点的下标的二进制
位一定有一位不一样,从而不被分在同一个组里,正确性被证明,这样只需要跑logk次即可。
复杂度 O(logk*(n+m)logn);
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<queue> #define maxn 100010 #define INF 2147483647 using namespace std; struct node { int ed,len,nxt; }; node edge[maxn*5]; int n,m,k,first[maxn],cnt,dis[maxn]; int love[maxn]; int set1_cnt,set2_cnt; int set1[maxn],set2[maxn]; bool vis[maxn]; inline void add_edge(int s,int e,int d) { cnt++; edge[cnt].ed=e; edge[cnt].len=d; edge[cnt].nxt=first[s]; first[s]=cnt; return; } inline void dijkstra() { priority_queue < pair <int,int> > heap; for(register int i=1;i<=n;++i) dis[i]=INF,vis[i]=false; for(register int i=1;i<=set1_cnt;++i) { dis[set1[i]]=0; heap.push(make_pair(-dis[set1[i]],set1[i])); } while(!heap.empty()) { int p=heap.top().second; heap.pop(); if(vis[p]) continue; vis[p]=true; for(register int i=first[p];i;i=edge[i].nxt) { int e=edge[i].ed; int d=edge[i].len; int newd=dis[p]+d; if(newd<dis[e]) { dis[e]=newd; heap.push(make_pair(-dis[e],e)); } } } return; } inline void dijkstra_2() { priority_queue < pair <int,int> > heap; for(register int i=1;i<=n;++i) dis[i]=INF,vis[i]=false; for(register int i=1;i<=set2_cnt;++i) { dis[set2[i]]=0; heap.push(make_pair(-dis[set2[i]],set2[i])); } while(!heap.empty()) { int p=heap.top().second; heap.pop(); if(vis[p]) continue; vis[p]=true; for(register int i=first[p];i;i=edge[i].nxt) { int e=edge[i].ed; int d=edge[i].len; int newd=dis[p]+d; if(newd<dis[e]) { dis[e]=newd; heap.push(make_pair(-dis[e],e)); } } } return; } int main() { int t; scanf("%d",&t); while(t--) { memset(edge,0,sizeof(edge)); memset(first,0,sizeof(first)); cnt=0; scanf("%d%d%d",&n,&m,&k); for(register int i=1;i<=m;++i) { int s,e,d; scanf("%d%d%d",&s,&e,&d); add_edge(s,e,d); } int ans=2147483647; for(register int i=1;i<=k;++i) scanf("%d",&love[i]); for(register int i=0;(1<<i)<=k;++i) { set1_cnt=0; set2_cnt=0; for(register int j=1;j<=k;++j) { if(((j>>i)&1)==0) set1[++set1_cnt]=love[j]; else set2[++set2_cnt]=love[j]; } dijkstra(); for(register int j=1;j<=set2_cnt;++j) ans=min(ans,dis[set2[j]]); dijkstra_2(); for(register int j=1;j<=set1_cnt;++j) ans=min(ans,dis[set1[j]]); } printf("%d\n",ans); } return 0; }
原文地址:https://www.cnblogs.com/Hoyoak/p/11774033.html
- 基础篇章:关于 React Native 之 KeyboardAvoidingView 组件的讲解
- 基础篇章:关于 React Native 之 Slider 组件的讲解
- Java9 中的 9 个新特性
- ELK 集群 + X-Pack + Redis 集群 + Nginx ,实时日志(数据)搜集和分析的监控系统,简单上手使用
- 基础篇章:关于 React Native 之 Modal 组件的讲解
- 搭建高吞吐量 Kafka 分布式发布订阅消息 集群
- 你真的会用Retrofit2吗?Retrofit2完全教程
- 线程管理之获取和设置线程信息
- 线程创建和运行
- CentOs7.3 安装 MySQL 5.7.19 二进制版本
- Retrofit2.0通俗易懂的学习姿势,Retrofit2.0 + OkHttp3 + Gson + RxJava
- 3.Linux用户权限管理之三(文件与权限的设定)
- CentOs7.3 搭建 MySQL 5.7.19 主从复制,以及复制实现细节分析
- 1.Linux操作系统安装的5种方法以及心得
- 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 数组属性和方法
- java获取时间整点工具代码
- MyBatis预编译机制详解
- ActiveMQ NMS使用过程中的一点经验
- asp.net core 认证及简单集群
- WebAPI问题追踪日志记录过滤器
- 使用责任链模式消除if分支实践
- sql操作知识点个人笔记(SQLServer篇)
- kettle学习笔记(二)——kettle基本使用
- Spring源码深度解析(二)
- Repository个人实践
- 摩斯码编解码器
- kettle学习笔记(三)——kettle资源库、运行方式与日志
- 使用Let's Encrypted HPPTS你的网站
- .net core web api + Autofac + EFCore 个人实践
- kettle学习笔记(六)——kettle转换步骤