一下午都在学最短路dijkstra算法,总算是优化到了我能达到的水平的最快水准,然后列举一下我的优化历史,顺便总结总结

最朴素算法:

邻接矩阵存边+贪心||dp思想,几乎纯暴力,luoguTLE+MLE,

算优点??:但好写好想,比下面的代码短了差不多一半。

#include <iostream>
#include <cstdio>
#include <algorithm> using namespace std; int main()
{
int a[][],point,i,j,k,number,t1,t2,t3,u,n,min,book[]={},dis[];
int inf=;
scanf("%d %d\n",&point,&number);
int x;
cin>>x;
for(int i=;i<=point;i++)
for(int j=;j<=point;j++)
if(i==j)a[i][j]=;
else
a[i][j]=inf; for(int i=;i<=number;i++)
{
cin>>t1>>t2>>t3;
a[t1][t2]=t3;
} for(int i=;i<=point;i++)
dis[i]=a[][i]; for(int i=;i<=point-;i++)
{
min=inf;
for(int j=;j<=point;j++)
if(book[j]==&& dis[j]<min)
{
min=dis[j];
u=j;
}
book[u]=;
for(int k=;k<=point;k++)
{
if(a[u][k]<inf)
if(dis[k]>dis[u]+a[u][k])
dis[k]=dis[u]+a[u][k];
}
}
for(int i=;i<=point;i++)
cout<<i<<" "<<dis[i]<<endl;
return ;
}

第一次优化是前向星存边,

比上面最朴素的大量省空间,也省了部分时间,luogu上共用时1400ms+,一个点max接近五百。

 #include<iostream>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstring>
# include <cstdio>
#define maxi 2147483647; using namespace std; struct node
{
int z;//子节点
int val;//权值
int nexty;//最近父节点相同边编号
}edge[];
int head[];//某点为父节点运出的最后一条边
int cnt=,curr;// 边id inline void add(int a,int b,int c)//建立边向前星
{
cnt++;
edge[cnt].z=b;
edge[cnt].val =c;
edge[cnt].nexty =head[a];
head[a]=cnt;
} int main()
{
bool visit[]={};//是否已经加入最短路
long long dis[];//最短路存值
int n,m,s;
int a,b,c; scanf("%d%d%d",&n,&m,&s);
for(int i=;i<=n;i++)//初始化边权值为无穷
dis[i]=maxi;
for(int i=;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
}
//读入
curr=s;
dis[s]=;//到最初点距离为零
long long minn; while(!visit[curr])
{
visit[curr]=true;
for(int i=head[curr];i!=;i=edge[i].nexty )
{
if(!visit[edge[i].z]&&dis[edge[i].z]>dis[curr]+edge[i].val )
dis[edge[i].z]=dis[curr]+edge[i].val;
}
minn=;
for (int i=;i<=n;i++)
if(!visit[i]&&minn>dis[i])
{
minn=dis[i];
curr=i;
}
}
for (int i=;i<=n;i++)
printf("%lld ",dis[i]);
return ;
}

dijkstra优化1

最后的优化使代码长达近百行

主要运用:快读快写,优先队列(堆),前向星存边

不过这次优化使用结构体存边的时候发生了玄学错误,现在还是找不出错,不过用几个数组存边就AC了???

个人是喜欢结构体的,毕竟好写也整齐,但是没通过的话就不发出来了

这个复杂度又比上一个程序降低了不少,luogu 共用时500+ms,单个点max160+ms,比上一个快了大概3,4倍

下面这个是ac的数组存边。

 #include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <vector>
#include <stdio.h>
#include <string.h>
#define maxn 10005
#define maxm 500005
#define inf 2147483647 using namespace std; int n,m,cnt=;
bool visit[maxn];
int head[maxm],next[maxm],v[maxm],w[maxm],dist[maxn]; inline int read()
{
char ch;
int a=;
while(!(((ch=getchar())>='')&&(ch<='')));
a*=;a+=ch-'';
while(((ch=getchar())>='')&&(ch<=''))a*=,a+=ch-'';
return a;
} void write(int x)
{
if(x<) putchar('-'),x=-x;
if(x>)write(x/);
putchar(x%+'');
return ;
} struct cmp
{
bool operator()(int x,int y)
{
return dist[x]>dist[y];
}
}; void add(int a,int b,int c)
{
v[cnt]=b;
w[cnt]=c;
next[cnt]=head[a];
head[a]=cnt++;
return ;
} void dijk(int s)
{
priority_queue<int,vector<int>,cmp> q2;
while(!q2.empty() )
q2.pop() ;
dist[s]=;
q2.push(s);
while(!q2.empty() )
{
int x=q2.top() ;
q2.pop() ;
if(!visit[x])
{
visit[x]=true;
for(int i=head[x];i!=-;i=next[i])
{
int y=v[i];
dist[y]=min(dist[y],dist[x]+w[i]);
q2.push(y);
}
}
}
return ;
} int main()
{
int s;
n=read();
m=read();
s=read();
memset(head,-,sizeof(head));
memset(visit,,sizeof(visit));
for(int i=;i<=m;i++)
{
int a,b,c;
a=read(),b=read(),c=read();
add(a,b,c);
}
for(int i=;i<=n;i++)
dist[i]=inf;
dijk(s);
for(int i=;i<=n;i++)
write(dist[i]),putchar(' ');
return ;
}

dijkstra优化2

注意!这不是最优化dijkstra,只是个人能力能达到的最优化了。。。

写那么长的代码还是挺有成就感的

单源最短路dijkstra算法&&优化史的更多相关文章

  1. 单源最短路——dijkstra算法

    Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止. 问 ...

  2. 单源最短路Dijkstra算法——matlab实现

    迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止. 基本思想 通过Dijk ...

  3. 单源最短路(Dijkstra算法)

    #返回上一级 @Author: 张海拔 @Update: 2015-03-11 @Link: http://www.cnblogs.com/zhanghaiba/p/3514570.html Dijk ...

  4. 单源最短路-dijkstra算法(未优化)

    bool used[maxn]; int g[maxn][maxn]; // 边未联系的填充为INF int d[maxn]; void dijkstra(int s){ memset(g,false ...

  5. 单源最短路径(dijkstra算法)php实现

    做一个医学项目,当中在病例评分时会用到单源最短路径的算法.单源最短路径的dijkstra算法的思路例如以下: 如果存在一条从i到j的最短路径(Vi.....Vk,Vj),Vk是Vj前面的一顶点.那么( ...

  6. 【算法】单源最短路——Dijkstra

    对于固定起点的最短路算法,我们称之为单源最短路算法.单源最短路算法很多,最常见的就是dijkstra算法. dijkstra主要用的是一种贪心的思想,就是说如果i...s...t...j是最短路,那么 ...

  7. 单源最短路——Bellman-Ford算法

    1.Dijkstra的局限性 Dijkstra算法是处理单源最短路径的有效算法,但它局限于边的权值非负的情况,若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的. 列如以 ...

  8. 利用分支限界法求解单源最短路(Dijkstra)问题

    分支限界法定义:采用Best fist search算法,并使用剪枝函数的算法称为分支界限法. 分支限界法解释:按Best first的原则,有选择的在其child中进行扩展,从而舍弃不含有最优解的分 ...

  9. 牛客编程巅峰赛S1第6场 - 黄金&钻石&王者 C.星球游戏 (单源最短路,Dijkstra)

    题意:有\(n\)个点,\(m\)条双向边,两个方向的权值都是相等的,可以从\(A\)中的某个点出发走到\(B\)中的某个点,求所有路径中的最短距离,如果A和B中没有点联通,则输出\(-1\). 题解 ...

随机推荐

  1. CSS3及JS简单实现选项卡效果(适配手机端和pc端)

    想要适配手机端和pc端,有几种简单的方法,本人使用的是百分比分配的方法. *{ padding: 0; margin: 0; } body,html{ width: 100%; height: 100 ...

  2. MySQL基于mysqldump快速搭建从库

    MySQL主从搭建总的来说大致分为3个步骤: 1. 为主从实例添加复制所需参数以及创建复制用的账户 2. 需要 […]

  3. 基础架构之Docker私有库

    由于项目要容器化,所有搭建自己的镜像库也是很有必要的,不然发到直接使用官方的镜像库,速度绝对能让你头疼,这篇文章就介绍搭建自己的镜像私有库. (一)  环境要求 Centos 7.5.1804 Doc ...

  4. C# ——窗体和控件随着分辨率的变化自适应大小

    一.说明 我们自己编写程序的界面,会遇到各种屏幕分辨 率,只有自适应才能显的美观.实际上,做到这点也很简单,就是首先记录窗体和它上面控件的初始位置和大小,当窗体改变比例时,其控件的位置和大小也按此比 ...

  5. ES入门——数组的扩展

    1.Array.from() 该方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象,包括ES6新增的数据结构Set和Map.下面是 ...

  6. HTML5+CSS3开发移动端页面

    前提知识: 1.能够独立根据设计稿进行整套项目的需求.剖析及其开发: 2.对项目开发流程需要有一个基本的了解: 3.可以灵活运用切图.重构.前端的知识对项目进行灵活控制. 开发步骤之需求分析: 1.确 ...

  7. Linux系统下安装Gitlab

    Linux系统下安装Gitlab 一.简介 GitLab是利用 Ruby on Rails 一个开源的版本管理系统,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目.它拥有与 ...

  8. [转] RISC-V架构介绍

    1. RISC-V和其他开放架构有何不同 如果仅从"免费"或"开放"这两点来评判,RISC-V架构并不是第一个做到免费或开放的处理器架构. 在开始之前,我们先通 ...

  9. Hyper-V迁移---委派

    在Hyper-V管理器中-实时迁移,选择“使用kerberos",如图1所示 在AD中,找到Hyper-V宿主,分别设置委派,如图2所示    图1               图2

  10. javascript 随机数 生成 n-m

    例子:生成800-1500的随机整数,包含800但不包含1500 代码如下: 1500-800 = 700 Math.random()*700 var num = Math.random()*700 ...