单源最短路(手写堆+位运算优化+卡常+O2 = Luogu排名最后一页...)

如题

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<queue>
  5 #define rep(i,a,n) for(register int i = a;i <= n;++i)
  6 using namespace std;
  7
  8 void read(int& a){
  9     a = 0;char c = getchar();
 10     while(c < ‘0‘||c > ‘9‘)c = getchar();
 11     while(‘0‘ <= c&&c <= ‘9‘)a = a*10+c-‘0‘,c = getchar();
 12 }
 13
 14 const int Maxn = 1e5+10,Maxm = 2e5+10;
 15
 16 template<typename T>
 17
 18 void iswap(T &a,T &b){
 19     T t = a;
 20     a = b;
 21     b = t;
 22 }
 23
 24 template<typename T>
 25 struct Heap{
 26     T a[1000010];int n;
 27     Heap():n(0){}
 28     int size(){return n;}
 29     bool empty(){return !n;}
 30     T top(){return a[1];}
 31     void clear(){n = 0;}
 32
 33     void push(T x){
 34         a[++n] = x;
 35         int cur = n;
 36         while((cur>>1)&&a[cur>>1] < a[cur])
 37             iswap(a[cur>>1],a[cur]),cur >>= 1;
 38     }
 39
 40     void pop(){
 41         iswap(a[1],a[n--]);
 42         int cur = 1;
 43         while((cur<<1|1) <= n)
 44             if(a[cur<<1] < a[cur<<1|1]){
 45                 if(a[cur] < a[cur<<1|1]){
 46                     iswap(a[cur],a[cur<<1|1]);
 47                     cur = cur<<1|1;
 48                 }
 49                 else break;
 50             }
 51             else{
 52                 if(a[cur] < a[cur<<1]){
 53                     iswap(a[cur],a[cur<<1]);
 54                     cur <<= 1;
 55                 }
 56                 else break;
 57             }
 58         if((cur<<1) <= n&&a[cur] < a[cur<<1])
 59             iswap(a[cur],a[cur<<1]);
 60     }
 61 };
 62
 63 struct Edge{
 64     int to,wi,ne;
 65 }edges[Maxm];
 66
 67 int first[Maxn],d[Maxn],vis[Maxn];
 68 int n,m,s,cnte,x,y,z;
 69
 70 inline void add_edge(int fr,int to,int wi){
 71     edges[++cnte] = (Edge){to,wi,first[fr]};
 72     first[fr] = cnte;
 73 }
 74
 75 struct Node{
 76     int to,d;
 77     bool operator <(const Node x)const{
 78         return d > x.d;
 79     }
 80 };
 81
 82 Heap<Node> q;
 83
 84 inline void dijkstra(int s){
 85     memset(d,0x3f,sizeof(d));
 86     d[s] = 0; q.clear();
 87     q.push((Node){s,0});
 88     while(!q.empty()){
 89         int u = q.top().to; q.pop();
 90         if(vis[u])continue; vis[u] = 1;
 91         for(register int i = first[u];i;i = edges[i].ne){
 92             if(d[edges[i].to] > d[u]+edges[i].wi){
 93                 d[edges[i].to] = d[u]+edges[i].wi;
 94                 q.push((Node){edges[i].to,d[edges[i].to]});
 95             }
 96         }
 97     }
 98 }
 99
100 int main(){
101     read(n),read(m),read(s);
102     rep(i,1,m){
103         read(x),read(y),read(z);
104         add_edge(x,y,z);
105     }
106     dijkstra(s);
107     rep(i,1,n)printf("%d ",d[i]);
108 return 0;
109 }

原文地址:https://www.cnblogs.com/Wangsheng5/p/11816269.html

时间: 2024-10-08 10:00:29

单源最短路(手写堆+位运算优化+卡常+O2 = Luogu排名最后一页...)的相关文章

再看最短路算法 1 —— 单源最短路

学了多年的算法,最短路问题相当之常见———— 好久没写过最短路的问题了,直到昨天闲的无聊来了一题——BZOJ3402(HansBug:额才发现我弱到只能刷水的地步了TT) 一看这不是明显的单源最短路么呵呵...于是直接上来来了个dijkstra,而且用的是邻接表存储图—— Submit之后,结果却是—— 我立刻被雷到了QAQ...于是立刻改写spfa,结果—— 4000ms+(估计还不止)和192ms究竟是怎样的差距啊QAQ,本人虽然早都听说过spfa的强大性,但是未曾想过差距会如此可怕,于是H

UVA 658 It&#39;s not a Bug, it&#39;s a Feature! (单源最短路,dijkstra+优先队列,变形,经典)

题意:有n个bug,有m个补丁,每个补丁有一定的要求(比如某个bug必须存在,某个必须不存在,某些无所谓等等),打完出来后bug还可能变多了呢.但是打补丁是需要时间的,每个补丁耗时不同,那么问题来了:要打多久才能无bug?(同1补丁可重复打) 分析: n<=20,那么用位来表示bug的话有220=100万多一点.不用建图了,图实在太大了,用位图又不好玩.那么直接用隐式图搜索(在任意点,只要满足转移条件,任何状态都能转). 但是有没有可能每个状态都要搜1次啊?那可能是100万*100万啊,这样出题

单源最短路_SPFA_C++

当我们需要求一个点到其它所有点的最短路时,我们可以采用SPFA算法 代码特别好写,而且可以有环,但是不能有负权环,时间复杂度是O(α(n)n),n为边数,α(n)为n的反阿克曼函数,一般小于等于4 模板:http://www.cnblogs.com/hadilo/p/5934679.html 我感觉自己讲的不会很好,丢一个链接算了 算法详解:http://www.360doc.com/content/13/1208/22/14357424_335569176.shtml 伪代码是自己写的: 可以

【裸单源最短路:Dijkstra算法两种版本】hdu 1874 畅通工程续

Source : hdu 1874 畅通工程续 http://acm.hdu.edu.cn/showproblem.php?pid=1874 Problem Description 某省自从实行了很多年的畅通工程计划后,终于修建了很多路.不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多.这让行人很困扰. 现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离. Input 本题目包含多组数据,请处理到文件结束.

用scheme语言实现SPFA算法(单源最短路)

最近自己陷入了很长时间的学习和思考之中,突然发现好久没有更新博文了,于是便想更新一篇. 这篇文章是我之前程序设计语言课作业中一段代码,用scheme语言实现单源最段路算法.当时的我,花了一整天时间,学习了scheme并实现了SPFA算法,那天实现之后感觉很有成就感-在这里贴出来,以飨读者. 突然发现博客园不支持scheme语言,于是只能放弃高亮了.不得不说,scheme代码有没有高亮差别好大…… ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; 题目

图论:单源最短路与多源最短路问题

转载自http://acm.uestc.edu.cn/bbs/read.php?tid=5670 下载ppt帐号:qscqesze 密码:123456 ------------------------------------------------------------------- 单源最短路径: 松弛操作:D[i]表示源点s到i的当前最短路径1.条件:d[i]+e[i][j]<d[j]2.更新:d[j]=d[i]+e[i][j] Dijkstra算法: 算法初始时d[s] = 0,其余的点

【算法系列学习】Dijkstra单源最短路 [kuangbin带你飞]专题四 最短路练习 A - Til the Cows Come Home

https://vjudge.net/contest/66569#problem/A http://blog.csdn.net/wangjian8006/article/details/7871889 邻接矩阵实现的单源最短路 1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 #include<algorithm> 6 #include

Dijkstra算法 --- 单源最短路

Dijkstra算法适用于边权值为正的情况,可用于计算正权图上的单元最短路. 其伪代码如下: 设d[v0] = 0, 其他d[i] = INF 循环n次{ 在所有未标号的结点中,选取d值最小的结点x 给结点x加上永久标号 对于从x出发的所有边,执行松弛操作. } //松弛操作的伪代码如下: RELAX(u,v,w) if(u.d + w(u,v) < v.d){ v.d = w.d + w(u,v); pre[v] = u; } Dijkstra算法代码: /* Dijkstra 单源最短路算法

常见模板(欧拉筛素数,最小生成树,快排,并查集,单源最短路)

欧拉筛素数: #include<cstdio> #define maxn 10000000+10 using namespace std; int n,prime[5000001],num_prime=0,m; bool if_prime[maxn]; void euler(int limit) { for(int i=2;i<=limit;i++) { if(!if_prime[i]) prime[++num_prime]=i; for(int j=1;prime[j]*i<=l