最短路算法模板合集(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;
}

  接下来是邻接表版,用到了优先队列优化

 1 #include <iostream>
 2 #include <cmath>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <cstdio>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <queue>
 9 using namespace std;
10 #define INF 0xfffffff
11 #define maxn 1002
12
13 struct Node
14 {
15     int e;
16     int w;
17     friend bool operator < (Node A, Node B)
18     {
19         return  A.w > B.w;
20     }
21 };
22
23 bool vis[maxn];
24
25 int m, n;
26 vector< vector<Node> > G;
27
28 int Dij(int Star,int End)
29 {
30     Node P, Pn;
31     P.e = Star;
32     P.w = 0;
33
34     priority_queue<Node> Q;
35
36     Q.push(P);
37
38     while( !Q.empty() )
39     {
40         P = Q.top();
41         Q.pop();
42
43         if( vis[P.e] )
44             continue;
45
46         vis[P.e] = true;
47
48         if( P.e == End )
49             return P.w;
50
51         int len = G[P.e].size();
52
53         for(int i=0; i< len; i++)
54         {
55             Pn.e = G[P.e][i].e;
56             Pn.w = G[P.e][i].w + P.w;
57
58             if( !vis[Pn.e] )
59                 Q.push(Pn);
60         }
61     }
62     return -1;
63 }
64
65 int main()
66 {
67     Node P;
68     while(cin >> n >> m, m+n)
69     {
70         G.clear();
71         G.resize(n+1);
72
73         memset(vis,false,sizeof(vis));
74
75         for(int i=0; i<m; i++)
76         {
77             int a, b, c;
78             cin >> a >> b >> c;
79             P.e = b;
80             P.w = c;
81             G[a].push_back(P);
82             P.e = a;
83             G[b].push_back(P);
84         }
85
86         int ans = Dij(1,n);
87
88         cout << ans << endl;
89     }
90     return 0;
91 }

下面是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=1; k<=n; k++)
    {
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
            {
                G[i][j] = min(G[i][j], G[i][k] + G[k][j]);
            }
        }
    }
}
void Init()
{
    for(int i=0; i<=n; i++)
    {
        G[i][i] = 0;
        for(int j=0; j<i; j++)
            G[i][j] = G[j][i] = INF;
    }
}

int main()
{
    while(cin >> n >> m, m+n)
    {
        Init();
        for(int i=0; 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[1][n] << endl;
    }
    return 0;
}
时间: 2024-08-06 21:42:20

最短路算法模板合集(Dijkstar,Dijkstar(优先队列优化), 多源最短路Floyd)的相关文章

【模板】各类我会的傻逼算法模板合集(建设中

如果模板有误请杀了我 好了结束了可以关掉了 最大流dinic const int M=100005,N=2*1234; struct edge{ int to,next,cap; }e[M]; int cnt=1,last[N],h[N]; void insert(int a,int b,int c){ e[++cnt]=(edge){b,last[a],c};last[a]=cnt; e[++cnt]=(edge){a,last[b],c};last[b]=cnt; } bool bfs(in

字符串算法模板合集

1.KMP KMP模板 #include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #define ll long long #define INF 2147483647 #define mem(i,j) memset(i,j,sizeof(i)) #define F(i,j,n) for(register int i=j;i&

学渣乱搞系列之Tarjan模板合集

学渣乱搞系列之Tarjan模板合集 by 狂徒归来 一.求强连通子图 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <climits> 7 #include <vector> 8 #include <queue> 9 #incl

算法分类合集(转)

ACM 所有算法 数据结构 栈,队列,链表 哈希表,哈希数组 堆,优先队列双端队列可并堆左偏堆 二叉查找树Treap伸展树 并查集集合计数问题二分图的识别 平衡二叉树 二叉排序树 线段树一维线段树二维线段树 树状数组一维树状数组N维树状数组 字典树 后缀数组,后缀树 块状链表 哈夫曼树 桶,跳跃表 Trie树(静态建树.动态建树) AC自动机 LCA和RMQ问题 KMP算法 图论 基本图算法图广度优先遍历深度优先遍历拓扑排序割边割点强连通分量Tarjan算法双连通分量强连通分支及其缩点图的割边和

算法分类合集

ACM 所有算法 数据结构 栈,队列,链表 哈希表,哈希数组 堆,优先队列双端队列可并堆左偏堆 二叉查找树Treap伸展树 并查集集合计数问题二分图的识别 平衡二叉树 二叉排序树 线段树一维线段树二维线段树 树状数组一维树状数组N维树状数组 字典树 后缀数组,后缀树 块状链表 哈夫曼树 桶,跳跃表 Trie树(静态建树.动态建树) AC自动机 LCA和RMQ问题 KMP算法 图论 基本图算法图广度优先遍历深度优先遍历拓扑排序割边割点强连通分量Tarjan算法双连通分量强连通分支及其缩点图的割边和

最短路算法--模板

迪杰斯特拉算法(Dijkstra): Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径. 主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止. 1 #include <iostream> 2 using namespace std; 3 const int maxnum = 100; 4 const int maxint = 999999; 5 6 // 各数组都从下标1开始 7 int dist[maxnum]; // 表示当前点到源

【开坑】常见算法时间复杂度合集

*摘自交大ACM-ICPC系列丛书和网络 [数据结构] 二叉堆 并查集——初始化O(n),查找均摊O(1),合并均摊O(1) 树状数组——求和.修改O(logn) 左偏树——插入O(logn),求极值O(1),删除O(logn),合并O(logn) Trie——插入.查询O(length) Treap——插入.删除.查询O(logn) 伸展树 RMQ线段树 ST表 LCT 块状链表 树链剖分——剖分O(nlogn) [图论] [数学] [计算几何] [字符串]

【算法杂谈】各种最短路算法模板

[先来一发SPFA] int spfa_dfs(int u) { vis[u]=1; for(int k=f[u]; k!=0; k=e[k].next) { int v=e[k].v,w=e[k].w; if( d[u]+w < d[v] ) { d[v]=d[u]+w; if(!vis[v]) { if(spfa_dfs(v)) return 1; } else return 1; } } vis[u]=0; return 0; } SPFA [再来一个Floyd] for(int k=1;

模板合集

[快速幂运算] long long quickpow(long long x,long long n,long long k) { long long ans=1; while(n>0) { if(n&1) ans=(ans*x)%k; n>>=1; x=(x*x)%k; } return ans; } [矩阵快速幂] [树状数组] #define lowbit(x) x&(-x) void give(int x,int k) { for(int i=x;i<=n;