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

3 3
0 1 2 3 5 7
1 2 1
1 3 3
2 3 1

Sample Output

2

HINT

【注释】

请采用高效的堆来优化Dijkstra算法。

Source

WC2013营员交流-lydrainbowcat


配对堆不仅快,还支持修改操作

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]的更多相关文章

  1. BZOJ 3040: 最短路(road) ( 最短路 )

    本来想学一下配对堆的...结果学着学着就偏了... 之前 kpm 写过这道题 , 前面的边不理它都能 AC .. 我也懒得去写前面的加边了... 用 C++ pb_ds 库里的 pairing_hea ...

  2. BZOJ 3040 最短路 (堆优化dijkstra)

    这题不是裸的最短路么?但是一看数据范围就傻了.点数10^6,边数10^7.这个spfa就别想了(本来spfa就是相当不靠谱的玩意),看来是要用堆优化dijkstra了.但是,平时写dijkstra时为 ...

  3. BZOJ 3040最短路

    题目描述 给定一个 NN 个点, MM 条有向边的带权图,请你计算从 SS 出发,到每个点的距离. 数据保证你能从 SS 出发到任意点. 输入输出格式 输入格式: 第一行两个整数 NN . MM ,表 ...

  4. 最短路计数——Dijkstra

    题目: 给出一个N个顶点M条边的无向无权图,顶点编号为1−N.问从顶点1开始,到其他每个点的最短路有几条. ——传送门 受到题解的启发,用 Dijkstra A掉(手工代码) 思路: 1.无向无权图, ...

  5. Bzoj 2834: 回家的路 dijkstra,堆优化,分层图,最短路

    2834: 回家的路 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 62  Solved: 38[Submit][Status][Discuss] D ...

  6. Bzoj 2662: [BeiJing wc2012]冻结 dijkstra,堆,分层图,最短路

    2662: [BeiJing wc2012]冻结 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 647  Solved: 348[Submit][Sta ...

  7. BZOJ.2125.最短路(仙人掌 最短路Dijkstra)

    题目链接 多次询问求仙人掌上两点间的最短路径. 如果是在树上,那么求LCA就可以了. 先做着,看看能不能把它弄成树. 把仙人掌看作一个图(实际上就是),求一遍根节点到每个点的最短路dis[i]. 对于 ...

  8. BZOJ 2750 HAOI 2012 Road 高速公路 最短路

    题意: 给出一个有向图,求每条边有多少次作为最短路上的边(任意的起始点). 范围:n <= 1500, m <= 5005 分析: 一个比较容易想到的思路:以每个点作为起点,做一次SPFA ...

  9. hdoj 2544 最短路【dijkstra or spfa】

    最短路 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis ...

随机推荐

  1. c++(数据选择)

    在数学中,有一些数据选择的内容.举个例子来说,有这样一组数据:1.2.3.4.现在我们打算从中挑选出1个数据,那么有几种选择呢?结果应该是1.2.3.4:那么如果挑选2个数据呢,怎么选呢?那么结果应该 ...

  2. 独立成分分析(ICA)的模拟实验(R语言)

    本笔记是ESL14.7节图14.42的模拟过程.第一部分将以ProDenICA法为例试图介绍ICA的整个计算过程:第二部分将比较ProDenICA.FastICA以及KernelICA这种方法,试图重 ...

  3. C++ enum用法小技巧

    enum DeviceDataType :int    {        None = 0,              SourceRGBA32 = 1,               Keying = ...

  4. SQL用了Union后的排序问题

    最近使用SQL语句进行UNION查询,惊奇的发现:SQL没问题,UNION查询也没问题,都可以得到想要的结果,可是在对结果进行排序的时候,却出问题了. 1.UNION查询没问题 SELECT `id` ...

  5. destoon数据库表解释说明

    ----------------------------- 公司认证:vcompany 实名认证:vtarde ============================================ ...

  6. 邓_php_笔试!!!

    函数总结: ---------------------------------------------------------------------- 数组: 1.数组转换为字符串: implode ...

  7. ffmpeg批量实现视频转码命令行

    ffmpeg实现视频转码命令行,result需要提前建好作为保存转码后的视频路径: ffmpeg -i .mp4 -vcodec h264 "result\1.mp4" 当有大量视 ...

  8. 用C#编写Linux守护进程

    如果要在Red Hat Enterprise Linux上将.NET Core进程作为后台进程运行,则可以创建自定义systemd单元.今天我将为.NET Core编写两个自定义系统单元的例子.一个是 ...

  9. es6重点笔记:let,const

    一,let 先看代码: var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i) }; } a ...

  10. Spring+redis整合遇到的问题集以及注意事项

    redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set ...