Dijskra 算法理解
第一种,关键词:单源最短路径,权值非负,邻接矩阵存图,复杂度O(n ^ 2 )
算法在图论中较为常用,依靠与其他点构建联结依次更新地图上的最小值,最后求出答案。
应对题型:n个点,m条边,无边权,由点s到点t最短距离为多少?
PS:由于是用二维数组存图,当点数超过1e3 时会T。
// Create by 川和 on 2021/5/10
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <stack>
#include <map>
#include <iomanip>
#include <queue>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <set>
using namespace std;
#define pb push_back
#define LL long long
#define INF 0x3f3f
const int maxn = 1e3 + 17;
bool vis[maxn];
int mp[maxn][maxn], lowcost[maxn], pre[maxn];
int n, m;
void Dij(int beg) {
for (int i = 1; i <= n; i++) {
vis[i] = false;
mp[i][i] = 0;
lowcost[i] = mp[beg][i];
pre[i] = -1;
}
lowcost[beg] = 0, vis[beg] = true;
for (int j = 1; j <= n; j++) {
int k = -1, min = INF;
for (int i = 1; i <= n; i++) {
if (!vis[i] && lowcost[i] < min) {
min = lowcost[i];
k = i;
}
}
if (k == -1) break;
vis[k] = true;
for (int i = 1; i <= n; i++) {
if (lowcost[k] + mp[k][i] < lowcost[i]) {
lowcost[i] = lowcost[k] + mp[k][i];
pre[i] = k;
}
}
}
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &m);
memset(mp, INF, sizeof mp);
while (m--) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
mp[a][b] = c;
mp[b][a] = c;
}
Dij(1);
printf("%d\n",lowcost[n]);
}
}