最短路径¶
有向连通图¶
单源最短路径问题¶
Djikstra算法¶
适用范围: 存在重边、自环、边权非负值
- 时间复杂度: O(nlogn)
- 可求出从给定一个点到图中可到达的点的最短路径
算法分析:采用贪心思想
借助优先队列实现小根堆,每次选取最短边进行建图
AC code
#include <bits/stdc++.h>
#define debug(x) cout << #x << ' ' << x << '\n'
#define endl '\n'
using namespace std;
typedef pair<int, int> PII;
typedef long long ll;
const int N = 150010, mod = 1e9 + 7, inf = 0x3f3f3f3f;
int n, m;
struct node {
int pos, dist;
bool operator<(const node &b) const
{
return dist > b.dist;
}
};
vector<node> G[N];
int d[N];
int vis[N];
int dijkstra(int x)
{
memset(d, 0x3f, sizeof d);
priority_queue<node> q;
q.push({x, 0});
d[x] = 0;
while(q.size())
{
auto t = q.top();
q.pop();
if(vis[t.pos]) continue;
vis[t.pos] = 1;
for(auto v : G[t.pos])
{
if(d[v.pos] > d[t.pos] + v.dist)
{
d[v.pos] = d[t.pos] + v.dist;
q.push({v.pos, d[v.pos]});
}
}
}
return d[n];
}
void solve()
{
cin >> n >> m;
for(int i = 1; i <= m; i ++)
{
int a, b, dist;
cin >> a >> b >> dist;
G[a].push_back({b, dist});
}
int res = dijkstra(1);
if(res < inf) cout << res << endl;
else cout << -1 << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
solve();
return 0;
}
SPFA算法¶
基于bellman_ford算法优化
适用范围: 存在重边、自环、边权正负、不存在负权回路
- 时间复杂度: O(nlogn)
- 可求出从给定一个点到图中可到达的点的最短路径
算法分析:动态规划
借助队列存储更新结点,将存储的结点更新其后继结点
AC code
#include <bits/stdc++.h>
#define debug(x) cout << #x << ' ' << x << '\n'
#define endl '\n'
using namespace std;
typedef pair<int, int> PII;
typedef long long ll;
const int N = 100010, mod = 1e9 + 7, inf = 0x3f3f3f3f;
int n, m;
struct node{
int pos, dist;
};
vector<node> G[N];
int d[N], vis[N];
int spfa(int x)
{
memset(d, 0x3f, sizeof d);
queue<int> q;
q.push(x);
d[x] = 0;
vis[x] = 1;
while(q.size())
{
auto t = q.front();
q.pop();
vis[t] = 0;
for(auto v : G[t])
{
if(d[v.pos] > d[t] + v.dist)
{
d[v.pos] = d[t] + v.dist;
if(!vis[v.pos])
{
q.push(v.pos);
vis[v.pos] = 1;
}
}
}
}
return d[n];
}
void solve()
{
cin >> n >> m;
for(int i = 1; i <= m; i ++)
{
int a, b, dist;
cin >> a >> b >> dist;
G[a].push_back({b, dist});
}
int res = spfa(1);
if(res < inf / 2) cout << res << endl;
else cout << "impossible" << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
solve();
return 0;
}
多源最短路问题¶
foryd算法¶
解决任意两点之间的最短路径问题, foryd算法只能处理矩阵网格图
时间复杂度: O(n^3)
算法分析:动态规划