最短路算法模板合集(Dijkstar,Dijkstar(优先队列优化), 多源最短路Floyd)
再开始前我们先普及一下简单的图论知识
图的保存:
1.邻接矩阵。 G[maxn][maxn];
2.邻接表
邻接表我们有两种方式
(1)vector< Node > G[maxn];
这个是之前就定义了图的大小了,再下面使用的时候就不用对图的大小进行申请了, 但是因为是直接申请了大小
要对图进行初始化,因此可能在某些题目中这样使用的话会超时
(2)vector< vector<Node> > G;
这个是未定义大小,但是在使用之前要对其的大小内存进行申请。
G.resize(n+1);
Dijkstra's Algorithm
算法思想:
1.从源点出发源点所有能一步到达的点的距离更新,然后从除源点外的所有点之中找出距离源点最近的点。
2.然后更新我们之前所找到的最短路点所有连接的点,但是要求这个点未曾被当做最短点处理过
3.重复上述操作n次。
单源最短路 我们还可以对他进行优先队列优化下面是以HDU2544为模板的用Dijkstra's Algorithm
邻接矩阵版,不用优先队列优化
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
#define INF 0xfffffff
#define maxn 1002 int G[maxn][maxn];//保存图
int dist[maxn];//表示从起点到第i点的距离
bool vis[maxn];//判断这个点是否被参观过
int m, n;//边数 m 顶点数 n void Init()
{
for(int i=0; i<=n; i++)
{
vis[i] = false;
dist[i] = INF;
for(int j=0; j<=i; j++)
G[i][j] = G[j][i] = INF;
}
}
int Dij(int Star,int End)//起点 --- 终点
{
dist[Star] = 0;
for(int i=1; i<=n; i++)
{
int index = 0, Min = INF;
for(int j=1; j<=n; j++)
{
if( !vis[j] && Min > dist[j] )//找出没有被参观过,并且距离起点最近的点
Min = dist[j], index = j;
} vis[index] = true; for(int j=1; j<=n; j++)//更新所有未曾到达的点距离,使之成为最近的点
{
if( !vis[j] && dist[j] > dist[index] + G[index][j] )
dist[j] = dist[index] + G[index][j];
}
} return dist[End]; } int main()
{
while(cin >> n >> m, m + n)
{
Init(); int a, b , c; for(int i=0; i<m; i++)
{
cin >> a >> b >> c;
G[a][b] = min(G[a][b], c);
G[b][a] = G[a][b];
} int ans = Dij(1,n); cout << ans << endl;
}
return 0;
}
接下来是邻接表版,用到了优先队列优化
#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
#define INF 0xfffffff
#define maxn 1002 struct Node
{
int e;
int w;
friend bool operator < (Node A, Node B)
{
return A.w > B.w;
}
}; bool vis[maxn]; int m, n;
vector< vector<Node> > G; int Dij(int Star,int End)
{
Node P, Pn;
P.e = Star;
P.w = ; priority_queue<Node> Q; Q.push(P); while( !Q.empty() )
{
P = Q.top();
Q.pop(); if( vis[P.e] )
continue; vis[P.e] = true; if( P.e == End )
return P.w; int len = G[P.e].size(); for(int i=; i< len; i++)
{
Pn.e = G[P.e][i].e;
Pn.w = G[P.e][i].w + P.w; if( !vis[Pn.e] )
Q.push(Pn);
}
}
return -;
} int main()
{
Node P;
while(cin >> n >> m, m+n)
{
G.clear();
G.resize(n+); memset(vis,false,sizeof(vis)); for(int i=; i<m; i++)
{
int a, b, c;
cin >> a >> b >> c;
P.e = b;
P.w = c;
G[a].push_back(P);
P.e = a;
G[b].push_back(P);
} int ans = Dij(,n); cout << ans << endl;
}
return ;
}
下面是Floyd算法
Floyd是求多源最短路, 即可以求出所有点对之间的最短路
这个算法就只要注意两点就行了,初始化的时候 G[i][i] = 0, 其他的初始化为INF
#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
#define INF 0xfffffff
#define maxn 1002 int G[maxn][maxn];
int dist[maxn][maxn];
int m, n; void Floyd()
{
for(int k=; k<=n; k++)
{
for(int i=; i<=n; i++)
{
for(int j=; j<=n; j++)
{
G[i][j] = min(G[i][j], G[i][k] + G[k][j]);
}
}
}
}
void Init()
{
for(int i=; i<=n; i++)
{
G[i][i] = ;
for(int j=; j<i; j++)
G[i][j] = G[j][i] = INF;
}
} int main()
{
while(cin >> n >> m, m+n)
{
Init();
for(int i=; i<m; i++)
{
int a, b, c;
cin >> a >> b >> c;
G[a][b] = min(G[a][b],c);
G[b][a] = G[a][b];
} Floyd(); cout << G[][n] << endl;
}
return ;
}
最短路算法模板合集(Dijkstar,Dijkstar(优先队列优化), 多源最短路Floyd)的更多相关文章
- ACM算法模板 · 一些常用的算法模板-模板合集(打比赛专用)
ACM算法模板 · 一些常用的算法模板-模板合集(打比赛专用)
- 学渣乱搞系列之Tarjan模板合集
学渣乱搞系列之Tarjan模板合集 by 狂徒归来 一.求强连通子图 #include <iostream> #include <cstdio> #include <cs ...
- ACM模板合集
写在前面: 第一年小白拿铜牌,第二年队友出走,加上疫情原因不能回校训练导致心底防线彻底崩盘,于是选择退役. 自从退役之后,一直想我打了那么久的ACM,什么也没留下觉得很难受,突然想到我打ACM的时候, ...
- 最短路算法模板--SPFA
初见SPFA时,直接认成了优先队列优化的Dijkstra,经过几位大佬的指点,我终于明白了他们的差异. Dijkstra是保证已经出队过的点不再入队,SPFA是已经在队列中不再入队.比较起来,SPFA ...
- 有趣的线段树模板合集(线段树,最短/长路,单调栈,线段树合并,线段树分裂,树上差分,Tarjan-LCA,势能线段树,李超线段树)
线段树分裂 以某个键值为中点将线段树分裂成左右两部分,应该类似Treap的分裂吧(我菜不会Treap).一般应用于区间排序. 方法很简单,就是把分裂之后的两棵树的重复的\(\log\)个节点新建出来, ...
- 【转】Tarjan算法 资料合集
http://blog.csdn.net/fuyukai/article/details/51039788 Tarjan三大算法之双连通分量(割点,桥) Robert Endre Tarjan是一个美 ...
- 最短路算法模板SPFA、disjkstra、Floyd
朴素SPFA(链表建边) #include <iostream> #include <cstdio> #include <cstring> #include < ...
- (模板)poj2387(dijkstra+优先队列优化模板题)
题目链接:https://vjudge.net/problem/POJ-2387 题意:给n个点(<=1000),m条边(<=2000),求结点n到结点1的最短路. 思路:dijkstra ...
- 最短路问题的三种算法&模板
最短路算法&模板 最短路问题是图论的基础问题.本篇随笔就图论中最短路问题进行剖析,讲解常用的三种最短路算法:Floyd算法.Dijkstra算法及SPFA算法,并给出三种算法的模板.流畅阅读本 ...
随机推荐
- Entity Framework CodeFirst------数据迁移(二)
众所周知当我们的项目涉及到数据库时,随着需求或大或小的 变更后,我们之前设计好的数据模型会发生部分的更改,导致数据表.或者数据字段的增加.修改等,这个时候我们就需要对数据库结构进行修改,如果我们之前采 ...
- android中的文件操作详解以及内部存储和外部存储(转载)
原文链接:http://m.blog.csdn.net/article/details?id=17725989 摘要 其实安卓文件的操作和java在pc环境下的操作并无二致,之所以需要单独讲解是因为安 ...
- css.day03
css的分类(位置): css层叠样式表 1.内嵌 样式表 2.行内样式表 3. 外连 css选择器分类 基础选择器 标签 id选择器 类选择器 复合选择器 交集选择器(标签指定式) span.on ...
- Android开发手记(21) 遍历文件夹
我们在遍历文件夹的时候由于涉及到SD卡相关操作,所以我们需要添加如下权限: <uses-permission android:name="android.permission.WRIT ...
- 抓取锁的sql语句-第四次修改
--完成情况 变量V_BLOCKING_SID 用来动态抓取 产生锁的会话id,输出参数没有任何问题,但是执行报错 标识符无效! CREATE OR REPLACE PROCEDURE SOLV ...
- CSS代码语法
css 样式由选择符和声明组成,而声明又由属性和值组成,如下图所示: 选择符:又称选择器,指明网页中要应用样式规则的元素,如本例中是网页中所有的段(p)的文字将变成蓝色,而其他的元素(如ol)不会受到 ...
- Android Studio使用技巧
1.ctrl+shift+F格式化代码时自动换行: 在settings里面找到Editor>General>Soft Wraps>设置选中Use soft wraps in edit ...
- 你好,C++(34)有一只叫做多利的羊 6.2.4 拷贝构造函数
6.2.4 拷贝构造函数 在C++世界中,除了需要使用构造函数直接创建一个新的对象之外,有时还需要根据已经存在的某个对象创建它的一个副本,就像那只叫做多利的羊一样,我们希望根据一只羊创建出来另外一只 ...
- html form <label>标签基础语法结构与使用案例教程(转载)
在表单布局中会遇到label标签的使用,label没有任何样式效果,有触发对应表单控件功能.比如我们点击单选按钮或多选框前文字对应选项就能被选中,这个就是对文字加了<label>标签实现. ...
- 关于表单的jQuery练习
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...