BZOJ 3040: 最短路(road) [Dijkstra + pb_ds]
3040: 最短路(road)
Time Limit: 60 Sec Memory Limit: 200 MB
Submit: 2476 Solved: 814
[Submit][Status][Discuss]
Description
N个点,M条边的有向图,求点1到点N的最短路(保证存在)。
1<=N<=1000000,1<=M<=10000000
Input
第一行两个整数N、M,表示点数和边数。
第二行六个整数T、rxa、rxc、rya、ryc、rp。
前T条边采用如下方式生成:
1.初始化x=y=z=0。
2.重复以下过程T次:
x=(x*rxa+rxc)%rp;
y=(y*rya+ryc)%rp;
a=min(x%n+1,y%n+1);
b=max(y%n+1,y%n+1);
则有一条从a到b的,长度为1e8-100*a的有向边。
后M-T条边采用读入方式:
接下来M-T行每行三个整数x,y,z,表示一条从x到y长度为z的有向边。
1<=x,y<=N,0<z,rxa,rxc,rya,ryc,rp<2^31
Output
一个整数,表示1~N的最短路。
Sample Input
0 1 2 3 5 7
1 2 1
1 3 3
2 3 1
Sample Output
HINT
【注释】
请采用高效的堆来优化Dijkstra算法。
Source
配对堆不仅快,还支持修改操作
point_iterator 是它的迭代器
q.modify(迭代器,修改成的元素)
不知道为什么手写结构体就不行,用pair就可以
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <ext/pb_ds/priority_queue.hpp>
typedef long long ll;
#define pa pair<ll,int>
#define mp make_pair
using namespace std;
using namespace __gnu_pbds;
typedef __gnu_pbds::priority_queue<pa,greater<pa> > heap;
const int N=1e6+,M=1e7+;
const ll INF=1e15;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,m,T,rxa,rxc,rya,ryc,rp,a,b;
int x,y,z;
struct edge{
int v,w,ne;
}e[M];
int cnt,h[N];
inline void ins(int u,int v,int w){
cnt++;
e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt;
} ll d[N];
heap q;
heap::point_iterator id[N];
void dij(){
for(int i=;i<=n;i++) d[i]=INF;
d[]=;id[]=q.push(mp(,));
while(!q.empty()){
int u=q.top().second;q.pop(); //printf("u %d\n",u);
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v,w=e[i].w;
if(d[v]>d[u]+w){
d[v]=d[u]+w;
if(id[v]!=) q.modify(id[v],mp(d[v],v));
else id[v]=q.push(mp(d[v],v));
}
}
}
}
int main(){
//freopen("in.txt","r",stdin);
n=read();m=read();
T=read();rxa=read();rxc=read();rya=read();ryc=read();rp=read();
m=m-T;
while(T--){
x=y=z=;
x=((ll)x*rxa+rxc)%rp;
y=((ll)y*rya+ryc)%rp;
a=min(x%n+,y%n+);
b=max(y%n+,y%n+);
ins(a,b,-*a);
}
while(m--) x=read(),y=read(),z=read(),ins(x,y,z);
dij();
printf("%lld",d[n]);
}
于是我又去交了一遍luogu的模板题,不开O2 380ms,比SLF优化后的spfa还快
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <ext/pb_ds/priority_queue.hpp>
#define pa pair<int,int>
#define mp make_pair
using namespace std;
using namespace __gnu_pbds;
typedef __gnu_pbds::priority_queue<pa,greater<pa> > heap;
const int N=1e4+,M=5e5+,INF=;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,m,s,u,v,w;
struct edge{
int v,ne,w;
}e[M];
int h[N],cnt=;
inline void ins(int u,int v,int w){
cnt++;
e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt;
} heap q;
heap::point_iterator it[N];
int d[N];
void dij(int s){
for(int i=;i<=n;i++) d[i]=INF;
d[s]=;
it[s]=q.push(mp(,s));
while(!q.empty()){
int u=q.top().second;q.pop();
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v,w=e[i].w;
if(d[v]>d[u]+w){
d[v]=d[u]+w;
if(it[v]!=) q.modify(it[v],mp(d[v],v));
else it[v]=q.push(mp(d[v],v));
}
}
}
}
int main(){
n=read();m=read();s=read();
for(int i=;i<=m;i++){u=read();v=read();w=read();ins(u,v,w);}
dij(s);
for(int i=;i<=n;i++) printf("%d ",d[i]);
}
BZOJ 3040: 最短路(road) [Dijkstra + pb_ds]的更多相关文章
- BZOJ 3040: 最短路(road) ( 最短路 )
本来想学一下配对堆的...结果学着学着就偏了... 之前 kpm 写过这道题 , 前面的边不理它都能 AC .. 我也懒得去写前面的加边了... 用 C++ pb_ds 库里的 pairing_hea ...
- BZOJ 3040 最短路 (堆优化dijkstra)
这题不是裸的最短路么?但是一看数据范围就傻了.点数10^6,边数10^7.这个spfa就别想了(本来spfa就是相当不靠谱的玩意),看来是要用堆优化dijkstra了.但是,平时写dijkstra时为 ...
- BZOJ 3040最短路
题目描述 给定一个 NN 个点, MM 条有向边的带权图,请你计算从 SS 出发,到每个点的距离. 数据保证你能从 SS 出发到任意点. 输入输出格式 输入格式: 第一行两个整数 NN . MM ,表 ...
- 最短路计数——Dijkstra
题目: 给出一个N个顶点M条边的无向无权图,顶点编号为1−N.问从顶点1开始,到其他每个点的最短路有几条. ——传送门 受到题解的启发,用 Dijkstra A掉(手工代码) 思路: 1.无向无权图, ...
- Bzoj 2834: 回家的路 dijkstra,堆优化,分层图,最短路
2834: 回家的路 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 62 Solved: 38[Submit][Status][Discuss] D ...
- Bzoj 2662: [BeiJing wc2012]冻结 dijkstra,堆,分层图,最短路
2662: [BeiJing wc2012]冻结 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 647 Solved: 348[Submit][Sta ...
- BZOJ.2125.最短路(仙人掌 最短路Dijkstra)
题目链接 多次询问求仙人掌上两点间的最短路径. 如果是在树上,那么求LCA就可以了. 先做着,看看能不能把它弄成树. 把仙人掌看作一个图(实际上就是),求一遍根节点到每个点的最短路dis[i]. 对于 ...
- BZOJ 2750 HAOI 2012 Road 高速公路 最短路
题意: 给出一个有向图,求每条边有多少次作为最短路上的边(任意的起始点). 范围:n <= 1500, m <= 5005 分析: 一个比较容易想到的思路:以每个点作为起点,做一次SPFA ...
- hdoj 2544 最短路【dijkstra or spfa】
最短路 Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submis ...
随机推荐
- [国嵌攻略][098][Linux内核简介]
Linux系统架构 1.用户空间:应用程序.C函数库 2.内核空间:系统调用接口.内核.体系结构相关代码 Linux系统利用处理器不同的工作模式,使用其中的两个级别分别来运行Linux内核与应用程序, ...
- Content Provider Test过程中遇到的坑
Content Provider(内容提供器) 一.什么是Content Provider? 直接贴官方文档简介图,笔者太懒了,而且 坑 不在这
- java序列化反序列化深入探究
When---什么时候需要序列化和反序列化: 简单的写一个hello world程序,用不到序列化和反序列化.写一个排序算法也用不到序列化和反序列化.但是当你想要将一个对象进行持久化写入文件,或者你想 ...
- thinkphp5使用redis实现秒杀商品活动
如题,废话少说贴码为上↓ // 初始化redis数据列表 模拟库存50,redis搭建在centos中已开启 public function redisinit(){ $store=50; // 库存 ...
- 使用 EclEmma 进行覆盖测试
开源软件测试工具 EclEmma,它能够对由 Java 语言编写的程序进行覆盖测试,从而对程序运行的结果生成详尽的覆盖测试报告. UT-Junit 安装 EclEmma 插件 安装 EclEmma 插 ...
- Java中的SerialVersionUID
Java中的SerialVersionUID 序列化及SergalVersionUID困扰着许多Java开发人员.我经常会看到这样的问题,什么是SerialVersionUID,如果实现了Serial ...
- Oracle多表连接查询
连接:将一张表中的行按照某种条件和另一张表中的行连接起来形成一个新行的的过程. 根据连接查询返回的结果,分为3类: 内连接(inner join) 外连接(outer join) 交叉连接(cross ...
- 2017-07-07(zip unzip gzip gunzip)
zip压缩格式 zip zip 压缩文件名 源文件 (压缩文件) zip -r 压缩文件名 源文件 (压缩目录) unzip unzip 压缩名 .gz压缩格式 gzip gz ...
- 一步步使用BMC Atrium Orchestrator Vmware Infrastructure Event Monitor
本教程将一步步演示怎么使用BMC Atrium Orchestrator (BAO) Vmware Infrastructure Event Monitor来监控VSphere Webservice的 ...
- 转-Linux硬件装置和磁盘分区MBR
1 各硬件装置在Linux中的文件名 『在Linux系统中,每个装置都被当成一个文件来对待』 举例来说,SATA接口的硬盘的文件名即为/dev/sd[a-d],其中, 括号内的字母为a-d当中的任意一 ...