洛谷 P 5 3 0 4 [GXOI/GZOI2019]旅行者
题目描述
J 国有 n 座城市,这些城市之间通过 m 条单向道路相连,已知每条道路的长度。
一次,居住在 J 国的 Rainbow 邀请 Vani 来作客。不过,作为一名资深的旅行者,Vani 只对 J 国的 kk 座历史悠久、自然风景独特的城市感兴趣。
为了提升旅行的体验,Vani 想要知道他感兴趣的城市之间「两两最短路」的最小值(即在他感兴趣的城市中,最近的一对的最短距离)。
也许下面的剧情你已经猜到了——Vani 这几天还要忙着去其他地方游山玩水,就请你帮他解决这个问题吧。
输入格式
每个测试点包含多组数据,第一行是一个整数 T,表示数据组数。注意各组数据之间是互相独立的。
对于每组数据,第一行包含三个正整数 n,m,k表示 J 国的 n 座城市(从 1 \sim n1∼n 编号),m 条道路,Vani 感兴趣的城市的个数 k。
接下来 m 行,每行包括 3 个正整数 x,y,z,表示从第 xx 号城市到第 yy 号城市有一条长度为 z 的单向道路。注意 x,y 可能相等,一对 x,y 也可能重复出现。
接下来一行包括 k 个正整数,表示 Vani 感兴趣的城市的编号。
输出格式
输出文件应包含 T 行,对于每组数据,输出一个整数表示 k 座城市之间两两最短路的最小值。
输入输出样例
2
6 7 3
1 5 3
2 3 5
1 4 3
5 3 2
4 6 5
4 3 7
5 6 4
1 3 6
7 7 4
5 3 10
6 2 7
1 2 6
5 4 2
4 3 4
1 7 3
7 2 4
1 2 5 3
5
6
说明/提示
样例解释
对于第一组数据,1 到 3 最短路为5;1 到 6 最短路为 7;3,6 无法到达,所以最近的两点为 1,3,最近的距离为 5。
对于第二组数据,1 到 2 最短路为 6;5 到 3 最短路为 6;其余的点均无法互相达,所以最近的两点为 1,21,2和 5,3,最近的距离为 6。
数据范围
测试点编号 | nn 的规模 | mm 的规模 | 约定 |
---|---|---|---|
1 | 1,000≤1,000 | 5,000≤5,000 | 无 |
2 | 1,000≤1,000 | 5,000≤5,000 | 无 |
3 | 100,000≤100,000 | 500,000≤500,000 | 保证数据为有向无环图 |
4 | 100,000≤100,000 | 500,000≤500,000 | 保证数据为有向无环图 |
5 | 100,000≤100,000 | 500,000≤500,000 | 保证数据为有向无环图 |
6 | 100,000≤100,000 | 500,000≤500,000 | 无 |
7 | 100,000≤100,000 | 500,000≤500,000 | 无 |
8 | 100,000≤100,000 | 500,000≤500,000 | 无 |
9 | 100,000≤100,000 | 500,000≤500,000 | 无 |
10 | 100,000≤100,000 | 500,000≤500,000 | 无 |
思路:
这题的正解很高深,正解是O(nlog2n),是来回跑两次Dijkstra,然后在染色什么的,还有一种要劣一点的就是按位是1还是0将其分为两堆,然后跑最短路,但我要说的是一个畜生算法,一个比BK201还要畜生的算法。
众所周知,Dijkstra就是一种贪心,在不停的放缩中求得最最优解,所以原题让我们求最小的,那我们可以一个一个去跑然后求得最小的,这很显然会T掉,但可以优化一下,每次跑完最小值后直接结束程序不就行了吗?
原题是让我们找最小距离,变化一下不就成了找最近的点吗????Dijkstra的堆优化好像就有这样的性质,每次从堆顶取出一个元素,然后去跑,但堆顶的一定是最小的,所以当第一个出堆时,dis就已经确定,后面就不用跑了,自然万一图没有联通,最后就输出0x3f3f3f3f就可以了,
复杂度:
一下纯属玄学,可以直接跳过。
最快(暗指出题人不卡)O(m)的,但最坏,就会变成O(n2log n)感觉要慢很多但是思考一下两种情况
- 每遍访问到第 n−k 个点的时候,即:把所有的不感兴趣的点都访问过了。此时一定能找到一个感兴趣的点。而这种情况才是真的最坏情况。
- 假如我们构建出对于一个点,按照上面的情况让它需要把所有的不感兴趣的点都访问一遍,那么对于当前点确实是一个 (n-k)*log(n−k)的复杂度。但是我们会发现对于其他的点去再跑dijkstradijkstra的时候很难再跑到这个最坏复杂度。
这样似乎也挺快的。据说有人加了个快读,比STD还要快。。。。
代码
#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<bitset>
using namespace std;
const int maxn=1e6+;
struct no
{
int to;
int next;
int value;
}way[maxn];
int tot,head[maxn];
int add(int x,int y,int w)
{
way[++tot].next=head[x];
way[tot].to=y;
way[tot].value=w;
head[x]=tot;
}
long long dis[maxn];
struct node
{
int u;
long long d;
bool operator < (const node &rhs) const
{
return d>rhs.d;
}
};
priority_queue<node> q;
bitset<maxn> vis,fl;
int n,m,k;
long long dijkstra(int st)
{
while(!q.empty())
{
q.pop();
}
vis.reset();
memset(dis,0x3f,sizeof(dis));
q.push((node){st,});
dis[st]=;
while(!q.empty())
{
node fi=q.top();
q.pop();
int u=fi.u;
if(fl[u]&&u!=st)
{
return dis[u];
} if(!vis[u])
{
vis[u]=;
for(int i=head[u];i;i=way[i].next)
{
int v=way[i].to;
int w=way[i].value;
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
q.push((node){v,dis[v]});
}
}
}
}
return 0x3f3f3f3f;
}
int main()
{
int T;
cin>>T;
while(T--)
{
tot=;
memset(head,,sizeof(head));
fl.reset();
scanf("%d%d%d",&n,&m,&k);
for(int i=,u,v,w;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
}
for(int i=,u;i<=k;i++)
{
scanf("%d",&u);
fl[u]=;
}
long long ans=0x3f3f3f3f;
for(int i=;i<=n;i++)
{
if(fl[i])
{
ans=min(dijkstra(i),ans);
}
}
printf("%lld\n",ans);
}
return ;
}
最后的最后,不由得想吐槽一下,机房旁边的大佬(超链接)实在是太巨了,竟然还在搞什么
暴力碾标算,n^2过百万!!
数组开的大,不清也不怕!!
洛谷 P 5 3 0 4 [GXOI/GZOI2019]旅行者的更多相关文章
- 【BZOJ5506】[GXOI/GZOI2019]旅行者(最短路)
[BZOJ5506][GXOI/GZOI2019]旅行者(最短路) 题面 BZOJ 洛谷 题解 正着做一遍\(dij\)求出最短路径以及从谁转移过来的,反过来做一遍,如果两个点不由同一个点转移过来就更 ...
- [LOJ3087][GXOI/GZOI2019]旅行者——堆优化dijkstra
题目链接: [GXOI/GZOI2019]旅行者 我们考虑每条边的贡献,对每个点求出能到达它的最近的感兴趣的城市(设为$f[i]$,最短距离设为$a[i]$)和它能到达的离它最近的感兴趣的城市(设为$ ...
- P5304 [GXOI/GZOI2019]旅行者
题目地址:P5304 [GXOI/GZOI2019]旅行者 这里是官方题解 一个图 \(n\) 点 \(m\) 条边,里面有 \(k\) 个特殊点,问这 \(k\) 个点之间两两最短路的最小值是多少? ...
- 洛谷 P5304 [GXOI/GZOI2019]旅行者(最短路)
洛谷:传送门 bzoj:传送门 参考资料: [1]:https://xht37.blog.luogu.org/p5304-gxoigzoi2019-lv-xing-zhe [2]:http://www ...
- [洛谷P5304][GXOI/GZOI2019]旅行者
题目大意: 有一张 \(n(n\leqslant10^5)\) 个点 \(m(m\leqslant5\times10^5)\) 条边的有向有正权图,有$k(2\leqslant k\leqslant ...
- luogu P5304 [GXOI/GZOI2019]旅行者
传送门 所以这个\(5s\)是SMG 暴力是枚举每一个点跑最短路,然后有一个很拿衣服幼稚的想法,就是把所有给出的关键点当出发点,都丢到队列里,求最短路的时候如果当前点\(x\)某个相邻的点\(y\)是 ...
- BZOJ5506 GXOI/GZOI2019旅行者(最短路)
本以为是个二进制分组傻逼题https://www.cnblogs.com/Gloid/p/9545753.html,实际上有神仙的一个log做法https://www.cnblogs.com/asul ...
- [GXOI/GZOI2019]旅行者
就我感觉这道题很神仙吗/kel 仔细想想应该也是一种适用范围挺广的做法. 考虑我们可以通过dijkstra在O(nlogn)求出一个点集到另外一个点集的最短路. 那么我们可以通过一些划分点集的方式使得 ...
- [GXOI/GZOI2019]旅行者 (最短路)
题意 给定一个有向图,其中一些顶点为关键点.求这些关键点两两之间最小距离. 题解 考试时没怎么想写了50分暴力走了.以为是什么强连通分量的解法,结果就是个最短路.直接从关键点跑一次最短路dis[0], ...
随机推荐
- 六、springboot 简单优雅是实现短信服务
前言 上一篇讲了 springboot 集成邮件服务,接下来让我们一起学习下springboot项目中怎么使用短信服务吧. 项目中的短信服务基本上上都会用到,简单的注册验证码,消息通知等等都会用到.所 ...
- uniapp 用户拒绝授权再次调起授权-语音识别、微信地址、附近地址
小程序重构,采用 uniapp 框架.记录一下踩过的坑.关于用户拒绝再次调起授权,及如何识别语音识别.微信地址.附近地址的处理. 语音识别 组件 语音识别,小程序只有录音功能,若要识别录音文件,常规做 ...
- 破阵九解:Node和浏览器之事件循环/任务队列/异步顺序/数据结构
前言 本文内容比较长,请见谅.如有评议,还请评论区指点,谢谢大家! >> 目录 开门见山:Node和浏览器的异步执行顺序问题 两种环境下的宏任务和微任务(macrotask &&a ...
- 九、Executor框架
Executor框架 我们知道线程池就是线程的集合,线程池集中管理线程,以实现线程的重用,降低资源消耗,提高响应速度等.线程用于执行异步任务,单个的线程既是工作单元也是执行机制,从JDK1.5开始 ...
- PHP array_unique
1.函数的作用:移除数组中重复的值 2.函数的参数: @params array $array @params int $sort_flag SORT_REGULAR : 通常方法比较(不改变类型) ...
- Cocos2d-x 学习笔记(26) 从源码学习 DrawCall 的降低方法
[Cocos2d-x]学习笔记目录 本文链接:https://www.cnblogs.com/deepcho/cocos2dx-drawcall-glcalls 1. 屏幕左下角 我们通常在Cocos ...
- springboot Jar包 部署到Linux服务器运行脚本
1.jar包同级目录 , 如下: #!/bin/sh RESOURCE_NAME=demo.jar tpid=`ps -ef|grep $RESOURCE_NAME|grep -v grep|grep ...
- 研究了3天,终于将 Shader 移植到 Cocos Creator 2.2.0 上了!
预览 扫光特效-Fluxay2 马赛克像素特效-Mosaic 过渡效果-Transfer Shawn 花了3天时间,研究了Cocos Creator 2.2.0 的 Effect 语法,终于在1024 ...
- Flink 从 0 到 1 学习 —— 如何自定义 Data Source ?
前言 在 <从0到1学习Flink>-- Data Source 介绍 文章中,我给大家介绍了 Flink Data Source 以及简短的介绍了一下自定义 Data Source,这篇 ...
- python学习-异常处理之捕获异常与抛出异常(七)
捕获异常 python完整的异常处理语法结构如下: 特别说明: 1.try块是必需的,except块和finally,当try块没有出现异常时,程序会执行else块 2.try块后只有一个except ...