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 ...
随机推荐
- SQL中 decode() 函数介绍
decode() 函数的语法: Select decode(columnname,值1,翻译值1,值2,翻译值2,...值n,翻译值n,缺省值) From talbename Where … 其中:c ...
- kali linux (Raspberry Pi 3b) 更新失败 出现上面的问题
Invalid signature for Kali Linux repositories : “The following signatures were invalid: EXPKEYSIG ED ...
- 通过Ops Manager安装管理mongodb-3.4集群
node1 Ops Manager,mongodb,agent node2 mongodb,agent node3 mongodb,agent 参考文档 https://docs.opsmanager ...
- jQuery Ajax请求后台数据并在前台接收
1.ajax基本语法 <script> $(function(){ $('#sub').click(function(){ var username=$('#username').val( ...
- Hive(2)-Hive的安装,使用Mysql替换derby,以及一丢丢基本的HQL
一. Hive下载 1. Hive官网地址 http://hive.apache.org/ 2. 文档查看地址 https://cwiki.apache.org/confluence/display/ ...
- Hadoop参数调优
转自:http://blog.sina.com.cn/s/blog_6a67b5c50100vop9.html dfs.block.size 决定HDFS文件block数量的多少(文件个数),它会间接 ...
- unity独立游戏开发日记2018/09/27
今天优化了下昨天的代码,并且添加了树木和其他资源的生成.还修复了接近石头后,挖掘图标不出现的bug.目前可以在unity中稳定60-70fps. 详看文章:https://www.cnblogs.co ...
- redhat6.5安装oracle 11g
1.修改操作系统核心参数 在Root用户下执行以下步骤: 1)修改用户的SHELL的限制,修改/etc/security/limits.conf文件 输入命令:vi /etc/security/lim ...
- System.Speech使用
使用微软语音库 使用微软语音库可以很快速的制作一个小应用,比如一个唐诗的朗诵工具.本示例也是使用微软语音库,制作了一个唐诗宋词朗诵的应用,仅供加深学习印象 首先是要引入System.Speech库 然 ...
- CSS3实现3d菜单翻转
transform-style:flat | preserve-3d: 3d透视属性.针对子元素如何在3d空间相对其父元素渲染,这个属性声明在父元素上,并且他的子元素使用了transform才会有效. ...