NO2——最短路径
【Dijkstra算法】
- 复杂度O(n2)
- 权值必须非负
/* 求出点beg到所有点的最短路径 */
// 邻接矩阵形式
// n:图的顶点数
// cost[][]:邻接矩阵
// pre[i]记录beg到i路径上的父结点,pre[beg]=-1
// 返回:各点的最短路径lowcost[]以及路径pre[]
const int maxn=;
const int INF=0x3f3f3f3f; //防止后面溢出,这个不能太大
bool vis[maxn];
int pre[maxn];
void Dijkstra(int cost[][maxn],int lowcost[],int n,int beg)
{
for(int i=;i<n;i++) //点的编号从0开始
{
lowcost[i]=INF;vis[i]=false;pre[i]=-;
}
lowcost[beg]=;
for(int j=;j<n;j++)
{
int k=-;
int Min=INF;
for(int i=;i<n;i++)
if(!vis[i]&&lowcost[i]<Min)
{
Min=lowcost[i];
k=i;
}
if(k==-)break;
vis[k]=true;
for(int i=;i<n;i++)
if(!vis[i]&&lowcost[k]+cost[k][i]<lowcost[i])
{
lowcost[i]=lowcost[k]+cost[k][i];
pre[i]=k;
}
}
}
【Dijkstra算法+堆优化】
- 复杂度O(E*logE)
- 使用优先队列优化Dijkstra算法
//注意对vector<Edge>E[MAXN]进行初始化后加边
const int INF=0x3f3f3f3f;
const int maxn=;
struct qnode
{
int v;
int c;
qnode(int _v=,int _c=):v(_v),c(_c){}
bool operator <(const qnode &r)const
{
return c>r.c;
}
};
struct Edge
{
int v,cost;
Edge(int _v=,int _cost=):v(_v),cost(_cost){}
};
vector<Edge>E[maxn];
bool vis[maxn];
int dist[maxn];
void Dijkstra(int n,int start) //点的编号从1开始
{
memset(vis,false,sizeof(vis));
for(int i=;i<=n;i++)dist[i]=INF;
priority_queue<qnode>que;
while(!que.empty())que.pop();
dist[start]=;
que.push(qnode(start,));
qnode tmp;
while(!que.empty()){
tmp=que.top();
que.pop();
int u=tmp.v;
if(vis[u])continue;
vis[u]=true;
for(int i=;i<E[u].size();i++){
int v=E[tmp.v][i].v;
int cost=E[u][i].cost;
if(!vis[v]&&dist[v]>dist[u]+cost){
dist[v]=dist[u]+cost;
que.push(qnode(v,dist[v]));
}
}
}
}
void addedge(int u,int v,int w)
{
E[u].push_back(Edge(v,w));
}
【Bellman-ford算法】
- 复杂度O(V*E)
- 可以处理负边权图
//可以判断是否存在负环回路
//返回true,当且仅当图中不包含从源点可达的负权回路
//vector<Edge>E;
//先E.clear()初始化,然后加入所有边
const int INF=0x3f3f3f3f;
const int maxn=;
int dist[maxn];
struct Edge
{
int u,v;
int cost;
Edge(int _u=,int _v=,int _cost=):u(_u),v(_v),cost(_cost){} //构造函数
};
vector<Edge>E;
bool bellman_ford(int start,int n) //点的编号从1开始
{
for(int i=;i<=n;i++)dist[i]=INF;
dist[start]=;
for(int i=;i<n;i++) //最多做n-1次
{
bool flag=false;
for(int j=;j<E.size();j++)
{
int u=E[j].u;
int v=E[j].v;
int cost=E[j].cost;
if(dist[v]>dist[u]+cost)
{
dist[v]=dist[u]+cost;
flag=true;
}
}
if(!flag)return true; //没有负环回路
}
for(int j=;j<E.size();j++)
if(dist[E[j].v]>dist[E[j].u]+E[j].cost)
return false; //有负环回路
return true; //没有负环回路
}
【SPFA算法】
- 复杂度O(K*E)
//这个是队列实现,有时候改成栈实现会更加快,很容易修改
//这个复杂度是不定的
const int maxn=;
const int INF=0x3f3f3f3f;
struct Edge
{
int v;
int cost;
Edge(int _v=,int _cost=):v(_v),cost(_cost){}
};
vector<Edge>E[maxn];
void addedge(int u,int v,int w)
{
E[u].push_back(Edge(v,w));
}
bool vis[maxn]; //在队列标志
int cnt[maxn]; //每个点的入队列次数
int dist[maxn];
bool SPFA(int start,int n)
{
memset(vis,false,sizeof(vis));
for(int i=;i<=n;i++)dist[i]=INF;
vis[start]=true;
dist[start]=;
queue<int>que;
while(!que.empty())que.pop();
que.push(start);
memset(cnt,,sizeof(cnt));
cnt[start]=;
while(!que.empty())
{
int u=que.front();
que.pop();
vis[u]=false;
for(int i=;i<E[u].size();i++)
{
int v=E[u][i].v;
if(dist[v]>dist[u]+E[u][i].cost)
{
dist[v]=dist[u]+E[u][i].cost;
if(!vis[v])
{
vis[v]=true;
que.push(v);
if(++cnt[v]>n)return false; //cnt[i]为入队列次数,用来判定是否存在负环回路
}
}
}
}
return true;
}
【Floyd-Warshall算法】
- 复杂度O(n3)
- 边权非负
#include<cstdio>
using namespace std;
#define INF 1e9
const int maxn=+;
int n,m; //点数,边数,点从0到n-1编号
int dist[maxn][maxn]; //记录距离矩阵
int path[maxn][maxn]; //path[i][j]=x表示i到j的路径上(除i外)的第一个点是x.
void init()
{
for(int i=;i<n;i++)
for(int j=;j<n;j++)
{
dist[i][j] = i==j ? : INF; //其实这里d[i][j]应该还要通过输入读数据的
path[i][j] = j;
} //读取其他dist[i][j]的值
}
void floyd()
{
for(int k=;k<n;k++)
for(int i=;i<n;i++)
for(int j=;j<n;j++)
if(dist[i][k]<INF && dist[k][j]<INF )
{
if(dist[i][j]>dist[i][k]+dist[k][j])
{
dist[i][j] = dist[i][k]+dist[k][j];
path[i][j] = path[i][k];
}
else if(dist[i][j] == dist[i][k]+dist[k][j] &&path[i][j]>path[i][k])
{
path[i][j] = path[i][k]; //最终path中存的是字典序最小的路径
}
}
} int main()
{
//读n和m
init();
//读m条边
floyd();
//输出所求最短路径距离
return ;
}
NO2——最短路径的更多相关文章
- Johnson 全源最短路径算法
解决单源最短路径问题(Single Source Shortest Paths Problem)的算法包括: Dijkstra 单源最短路径算法:时间复杂度为 O(E + VlogV),要求权值非负: ...
- Floyd-Warshall 全源最短路径算法
Floyd-Warshall 算法采用动态规划方案来解决在一个有向图 G = (V, E) 上每对顶点间的最短路径问题,即全源最短路径问题(All-Pairs Shortest Paths Probl ...
- Dijkstra 单源最短路径算法
Dijkstra 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法,由计算机科学家 Edsger Dijkstra 于 1956 年 ...
- Bellman-Ford 单源最短路径算法
Bellman-Ford 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法.该算法由 Richard Bellman 和 Leste ...
- 最短路径算法-Dijkstra
Dijkstra是解决单源最短路径的一般方法,属于一种贪婪算法. 所谓单源最短路径是指在一个赋权有向图中,从某一点出发,到另一点的最短路径. 以python代码为例,实现Dijkstra算法 1.数据 ...
- bzoj 4016: [FJOI2014]最短路径树问题
bzoj4016 最短路路径问题 Time Limit: 5 Sec Memory Limit: 512 MB Description 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点 ...
- 51nod 1459 迷宫游戏 (最短路径—Dijkstra算法)
题目链接 中文题,迪杰斯特拉最短路径算法模板题. #include<stdio.h> #include<string.h> #define INF 0x3f3f3f3f ],v ...
- C++迪杰斯特拉算法求最短路径
一:算法历史 迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题.迪杰斯特拉算法主要特点是以 ...
- 求两点之间最短路径-Dijkstra算法
Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.D ...
随机推荐
- 轻量ORM-SqlRepoEx (五) 存储过程操作
.Net平台下兼容.NET Standard 2.0,一个实现以Lambda表达式转转换标准SQL语句,使用强类型操作数据的轻量级ORM工具,在减少魔法字串同时,通过灵活的Lambda表达式组合,实现 ...
- 轻量ORM-SqlRepoEx (四)INSERT、UPDATE、DELETE 语句
*本文中所用类声明见上一篇博文<轻量ORM-SqlRepoEx (三)Select语句>中Customers类 一.增加记录 1.工厂一个实例仓储 var repository = Rep ...
- Hibernate知识点小结(三)-->一对多与多对多配置
一.多表关系与多表设计 1.多表关系 一对一: 表的设计原则(分表原则): 优化表的性能 基于语意化分表 ...
- jdbc执行过程 jar包下载
工具和准备: MYSQL 8.0jar包: 链接:https://pan.baidu.com/s/1O3xuB0o1DxmprLPLEQpZxQ 提取码:grni 使用eclipse开发首先把jar包 ...
- Spirng+SpringMVC+Mybatis(一)
实习之后都是在别人搭配好环境的情况下进行一些业务的编写,脑袋已经不记得如何搭建一个ssm项目的,所以周末有空补了一下. 首先新建一个test数据库,并且在里面插入三条数据.如图下 编写一个User B ...
- 使用Python读取Dbf文件
DBF:一种特殊的文件格式!表示数据库文件,Foxbase,Dbase,Visual FoxPro等数据库处理系统所产生的数据库文件! DBF 数据库是常用的桌面型数据库,它曾经被各企业.事业单位广泛 ...
- 搭建docker registry (htpasswd 认证)
1,拉取docker registry 镜像 docker pull registry 2,创建证书存放目录 mkdir -p /home/registry 3,生成CA证书Edit your /et ...
- python的字典数据类型及常用操作
字典的定义与特性 字典是Python语言中唯一的映射类型. 定义:{key1: value1, key2: value2} 1.键与值用冒号“:”分开: 2.项与项用逗号“,”分开: 特性: 1.ke ...
- JSP/Servlet开发——第二章 JSP数据交互(二)
1. JSP 内置对象 application: ●application 对象类似于系统的 "全局变量", 用于同一个应用内的所有用户之问的数据共享: ●application对 ...
- JS高级. 03 混入式继承/原型继承/经典继承、拓展内置对象、原型链、创建函数的方式、arguments、eval、静态成员、实例成员、instanceof/是否在同一个原型链
继承:当前对象没有的属性和方法,别人有,拿来给自己用,就是继承 1 混入式继承 var I={ }; var obj = { name: 'jack', age:18, sayGoodbye : fu ...