迪杰斯特拉算法(Dijkstra)
模板一:
时间复杂度O(n2)
int dijkstra(int s,int m) //s为起点,m为终点
{
memset(dist,,sizeof(dist)); //初始化,dist数组用来储存s到各个点的距离
memset(v,,sizeof(v)); //初始化v数组,是否已标记
for(int i=;i<=n;++i) //++i返回的是引用,稍微快一点
{
dist[i]=e[s][i]; //初始化,e[s][i]数组表示是点s到点i的权值,数组e用来存有向图或无向图的权值,用INF初始化
}
for(int i=;i<=n;++i)
{
k=INF,u=;
for(int j=;j<=n;++j) //找出当前dist最小的点
{
if(!v[j]&&dist[j]<k)
{
k=dist[j];
u=j;
}
}
v[u]=; //标记
for(int j=;j<=n;++j) //更新与点u相连的点的权值和
{
if(!v[j]&&e[u][j]<INF&&dist[u]+e[u][j]<dist[j]) //比较从点s到点u载到点j的权值和点s直接到点j的权值
{
dist[j]=dist[u]+e[u][j];
}
}
}
return dist[m];
}
模板二:
时间复杂度 O(mlogn)m为边数,n为顶点数。
对于稀疏图的效果显著,对稠密图慎用。
const int INF = 0x3f3f3f3f;
const int maxn = ;
struct Edge
{
int from, to, dist;
Edge(int u, int v, int d) :from(u), to(v), dist(d) {}
};
struct HeapNode
{
int d, u;
HeapNode(int D,int U):d(D),u(U){}
bool operator < (const HeapNode& rhs) const {
return d > rhs.d;
}
};
struct Dijkstra
{
int n, m;
vector<Edge> edges;
vector<int> G[maxn]; //maxn要大于顶点数
bool done[maxn];
int d[maxn];
int p[maxn]; void init(int n)
{
this->n = n;
for (int i = ; i < n; ++i)
G[i].clear();
edges.clear();
} void addEdge(int from, int to, int dist)
{
edges.push_back(Edge(from, to, dist));
m = edges.size();
G[from].push_back(m - );
} void dijkstra(int s, int kk) //s为起点 kk为终点
{
priority_queue<HeapNode> Q;
for (int i = ; i < n; ++i)
d[i] = INF;
d[s] = ;
memset(done, , sizeof(done));
Q.push(HeapNode( , s ));
while (!Q.empty())
{
HeapNode x = Q.top();
Q.pop();
int u = x.u;
if (u == kk) //到终点就退出
{
printf("%d\n", x.d);
break;
}
if (done[u])
{
continue;
}
done[u] = true;
for (int i = ; i < G[u].size(); ++i)
{
Edge& e = edges[G[u][i]];
if (d[u] + e.dist < d[e.to])
{
d[e.to] = d[u] + e.dist;
p[e.to] = G[u][i];
Q.push(HeapNode(d[e.to], e.to ));
}
}
}
} };
放一道模板题
http://acm.hdu.edu.cn/showproblem.php?pid=2544
AC代码
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = ;
struct Edge
{
int from, to, dist;
Edge(int u, int v, int d) :from(u), to(v), dist(d) {}
};
struct HeapNode
{
int d, u;
HeapNode(int D,int U):d(D),u(U){}
bool operator < (const HeapNode& rhs) const {
return d > rhs.d;
}
};
struct Dijkstra
{
int n, m;
vector<Edge> edges;
vector<int> G[maxn]; //maxn要大于顶点数
bool done[maxn];
int d[maxn];
int p[maxn]; void init(int n)
{
this->n = n;
for (int i = ; i < n; ++i)
G[i].clear();
edges.clear();
} void addEdge(int from, int to, int dist)
{
edges.push_back(Edge(from, to, dist));
m = edges.size();
G[from].push_back(m - );
} void dijkstra(int s, int kk) //s为起点 kk为终点
{
priority_queue<HeapNode> Q;
for (int i = ; i < n; ++i)
d[i] = INF;
d[s] = ;
memset(done, , sizeof(done));
Q.push(HeapNode( , s ));
while (!Q.empty())
{
HeapNode x = Q.top();
Q.pop();
int u = x.u;
if (u == kk)
{
printf("%d\n", x.d);
break;
}
if (done[u])
{
continue;
}
done[u] = true;
for (int i = ; i < G[u].size(); ++i)
{
Edge& e = edges[G[u][i]];
if (d[u] + e.dist < d[e.to])
{
d[e.to] = d[u] + e.dist;
p[e.to] = G[u][i];
Q.push(HeapNode(d[e.to], e.to ));
}
}
}
} };
int n, m, x, y, k;
Dijkstra d;
int main()
{
while (cin>>n>>m)
{
d.init(n);
if (n == && m == )
break;
while (m--)
{
cin >> x >> y >> k;
d.addEdge(x - , y - , k);
d.addEdge(y - , x - , k);
}
d.dijkstra(, n - );
}
return ;
}
持续更新……
迪杰斯特拉算法(Dijkstra)的更多相关文章
- 迪杰斯特拉算法(Dijkstra) (基础dij+堆优化) BY:优少
首先来一段百度百科压压惊... 迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最 ...
- C# 迪杰斯特拉算法 Dijkstra
什么也不想说,现在直接上封装的方法: using System; using System.Collections.Concurrent; using System.Collections.Gener ...
- 图->最短路径->单源最短路径(迪杰斯特拉算法Dijkstra)
文字描述 引言:如下图一个交通系统,从A城到B城,有些旅客可能关心途中中转次数最少的路线,有些旅客更关心的是节省交通费用,而对于司机,里程和速度则是更感兴趣的信息.上面这些问题,都可以转化为求图中,两 ...
- 迪杰斯特拉算法dijkstra(可打印最短路径)
#include <iostream> #include <iomanip> #include <string> using namespace std; #def ...
- 迪杰斯特拉(dijkstra)算法的简要理解和c语言实现(源码)
迪杰斯特拉(dijkstra)算法:求最短路径的算法,数据结构课程中学习的内容. 1 . 理解 算法思想::设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合 ...
- 最短路径之迪杰斯特拉(Dijkstra)算法
迪杰斯特拉(Dijkstra)算法主要是针对没有负值的有向图,求解其中的单一起点到其他顶点的最短路径算法.本文主要总结迪杰斯特拉(Dijkstra)算法的原理和算法流程,最后通过程序实现在一个带权值的 ...
- dijkstra算法(迪杰斯特拉算法)
dijkstra算法(迪杰斯特拉算法) 用途:有向图最短路径问题 定义:迪杰斯特拉算法是典型的算法,一般的表述通常有两种方式,这里均采用永久和临时标号的方式,该算法要求图中不存在负权边 用永久和临时标 ...
- 理解最短路径——迪杰斯特拉(dijkstra)算法
原址地址:http://ibupu.link/?id=29 1. 迪杰斯特拉算法简介 迪杰斯特拉(dijkstra)算法是典型的用来解决最短路径的算法,也是很多教程中的范例,由荷兰计算机科 ...
- Dijkstra【迪杰斯特拉算法】
有关最短路径的最后一个算法——Dijkstra 迪杰斯特拉算法是由荷兰计算机科学家迪杰斯特拉于1959 年提出的,因此又叫迪杰斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路 ...
- c/c++ 图的最短路径 Dijkstra(迪杰斯特拉)算法
c/c++ 图的最短路径 Dijkstra(迪杰斯特拉)算法 图的最短路径的概念: 一位旅客要从城市A到城市B,他希望选择一条途中中转次数最少的路线.假设途中每一站都需要换车,则这个问题反映到图上就是 ...
随机推荐
- [暑假集训Day2T2]走廊泼水节
给定一棵n个点的图上的最小生成树,让你把它补成完全图,使得新图的MST还是给定的MST且边权和最小,输出需要增加的边权和. 设size[i]表示以i号为祖先的并查集的大小. 首先按边权排序,之后在做M ...
- NGUI的CheckBox的使用(toggle script)
一,我们先添加一个sprite,选择sprite,右键选择attach,添加box collider, 然后右键选择attach,添加toggle script,得到如下图结果 1,但是如果你没有给U ...
- vue简单的v-for - - 路由跳转
前几天写了一个特特特简单的小图片页面,主要用到的就是v-for遍历以及路由跳转到详情页.路由跳转需要在router文件夹下index.js引入. 导航栏(element ui导航栏为模板): < ...
- js操作对象属性用点和用中括号有什么不同
书读百遍其义自见 学习<JavaScript设计模式>一书时,学习工厂模式这一章节,发现了对象后使用中括号的情况,如下: var Factory=function(type,content ...
- Dubbo源码学习总结系列一 总体认识
本文写作时,dubbo最高版本是V2.6.0. 写这篇文章主要想回答以下4个问题: 一.dubbo是什么?完成了哪些主要需求? 二.dubbo适用于什么场景? 三.dubbo的总体架构是什么样的? ...
- iconfont图标symbol引用方式,有的图标不能通过设置color样式来修改颜色的解决办法
现象:iconfont安装后的图标,是通过symbol引用方式,有的图标不能通过color修改颜色的解决办法,有的又可以. <svg class="icon" aria-hi ...
- 04.Linux-CentOS系统SSH连接问题
问题:SSH远程连接时报错 Socket error Event: 32 Error: 10053.Connection closing...Socket close.Connection close ...
- 实现多线程的三种方法:Thread、Runnable和Callable
继承Thread类,重写run()方法 步骤: (1) 定义类继承Thread类 (2) 复写Thread类中的run方法. (3) 调用线程的start方法 (start方法有两种含义:1. 启动多 ...
- redhat 6.8 配置外网yum源
1.检查是否安装yum包 rpm -qa |grep yum 2. 删除自带的yum包 rpm -qa|grep yum|xargs rpm -e --nodeps 3. 下载yum包 wget ht ...
- rabbitmq路由规则
信道如何共用???? 几台机器共用一个channel 如何做到?