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 ...
随机推荐
- 菜鸟笔记 -- Chapter 6.3 对象
6.3 对象 Java是一门面向对象的程序设计语言,对象是由类抽象出来的,所有的问题都是通过对象来处理的,对象可以操作类的属性和方法解决相应的问题,所以了解对象的产生.操作和生存周期对学习Java语言 ...
- Oracle四舍五入,向上取整,向下取整
用oracle sql对数字进行操作: 取上取整.向下取整.保留N位小数.四舍五入.数字格式化 取整(向下取整): select floor(5.534) from dual; select trun ...
- ZLG zigbee 虚拟串口配置
一.设置网关工作模式: 在ZNetCom Utility工具中,将设置网关工作模式为 Real COM 模式 启动 ZNetCom Utility 搜索设备 获得设备信息 修改工作模式为:real c ...
- Spring框架中的IOC?
Spring中的org.springframework.beans包和org.SpringframeWork.context包构成了Spring框架IOC容器的基础.BeanFactory接口提供了一 ...
- 【CodeForces 660D】Number of Parallelograms(n个点所能组成的最多平行四边形数量)
You are given n points on a plane. All the points are distinct and no three of them lie on the same ...
- <CPP学习>第一天 第一个CPP程序 hello word
由于我是计算机类嵌入式专业的大一学生,之前一直使用的是生万物的C语言,了解了其过程性语言的特性及其基础语法,在大一下学期期末阶段想自学一下C++,其实在开学初就买了一本C++ Primer,但由于各种 ...
- IDEA中使用插件添加更多可选择的主题,使代码高亮,缓解视觉疲劳
1.点击 File-->settings(或Ctrl+Shift+S)打开IDE设置面板 点击plugins-->右侧选择Marketplace-->搜索框中输入Material-- ...
- 【PBR的基本配置】
PBR基于策略路由的配置 一:基于报文协议的本地PBR 1:首先进行理论分析:在SW1上利用基于报文报文协议类型的PBR,在sw1与sw3的连接链路上,利用acl制定允许tcp的报文通过3000,并与 ...
- Laravel -- Blade模板
{{--流程控制--}} @if($name == '1') this is 1 @elseif($name == '2') this.is 2 @else who am i? @endif @for ...
- 使用virtual安装Windows系列操作系统总结
最近在安装Windows操作系统的过程中,发现总是报错,无法安装成功,后来经过不断地摸索,发现根本的问题在于镜像,所以在以后的大文件传输下载后,一定要校验其MD5值是否与源文件一致,需要的朋友可以联系 ...