迪杰斯特拉算法(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,他希望选择一条途中中转次数最少的路线.假设途中每一站都需要换车,则这个问题反映到图上就是 ...
随机推荐
- java Semaphore信号灯
Semaphore实现的功能就类似2个公用电话,假如有10个人要打电话:那么只能2个人占有电话,8个需要等待.当2个人中 的任何一个人让开后,其中等待的另外8个人中又有一个人可以使用了等待的8个人中可 ...
- [HDU5807] [BestCoder Round #86 1004] Keep In Touch (DP)
[HDU5807] [BestCoder Round #86 1004] Keep In Touch (DP) 题面 有三个人从一张N个点无重边的有向无环图上的三个点出发,每单位时间,他们分别选择当前 ...
- 图例演示在Linux上快速安装软RAID的详细步骤
物理环境:虚拟机centos6.4 配置:8G内存.2*2核cpu.3块虚拟硬盘(sda,sdb,sdc,sdb和sdc是完全一样的) 在实际生产环境中,系统硬盘与数据库和应用是分开的, ...
- java中位运算和移位运算详解
一.位运算 (1)按 位 与 & 如果两个相应的二进制形式的对应的位数都为1,则结果为1,记为同1为1,否则为0.首先我们看一下对正数的运算 分别看一下正数和负数的具体运算步骤 ...
- go语言从例子开始之Example35.原子计数器
Go 中最主要的状态管理方式是通过通道间的沟通来完成的,我们在工作池的例子中碰到过,但是还是有一些其他的方法来管理状态的.这里我们将看看如何使用 sync/atomic包在多个 Go 协程中进行 原子 ...
- OutOfMemoryError系列(2): GC overhead limit exceeded
原因分析 JVM抛出 java.lang.OutOfMemoryError: GC overhead limit exceeded 错误就是发出了这样的信号: 执行垃圾收集的时间比例太大, 有效的运算 ...
- 八、请求post、get、jsonp
1.创建个 news 组件使用 2.在module.ts 引入模块 3.在使用的“Component”中不一样.这里是 http和jsonp 4.编写get请求查看效果 (1).编写好的get请求,点 ...
- spring cloud学习笔记四 熔断器Hystrix
我们知道分布式服务有这样一个特点,每一个微服务都有自己的业务,并且很多时候一个微服务的业务要依赖于其他微服务,如果这些相互关联的微服务中其中某个微服务请求失败时,就会导致其他调用它的微服务也会请求失败 ...
- svnkit 异常:Exception in thread "main" org.tmatesoft.svn.core.SVNException: svn: E200030: SQLite error
https://stackoverflow.com/questions/16063105/org-tmatesoft-sqljet-core-sqljetexception-busy-error-co ...
- python 的set定义
set是集合,跟数学中的集合一样不能重复没有顺序 set定义有两种方式 1. b=set([1, 2, 3, 4]) 2. a={"} 输出: b=set([1, 2, 3, 4])a={1 ...