1. problem
The shortest, as the name suggests, is to find the shortest path. Specifically, on a graph, given the starting point s and the end point t, remove the weight and minimal side, so that to reach from the s t.
2. resolve
1, floyd algorithm
This algorithm is a more violent algorithm, each enumeration three points A , B , C , if the DIS (A, B)> DIS (A, C) + DIS (C, B) , then the description, A- > b paths, I can select a point C , the dis (a, b) updates the value of DIS (a, C) + DIS (C, B) , we call such an operation a relaxed, continuously in constant enumeration in slack, DIS (a, B) will represent a-> b minimum distance.
2, dijkstra algorithm
① . Initially, S contains only a starting point s ; U comprising inter s other vertex outside, and U in the distance from the apex of " starting point s to the distance from the vertex " [ e.g., U vertex v distance is (s, v ) length, and s and v are not adjacent, then v is a distance ∞] .
② . From U elect the " shortest distance vertex k" , and the vertex k is added to S ; the same time, the U remove vertices k .
③ . Update U of each point to the starting point s distance. The reason why the update U distance vertices, due to the previous step to determine the k is determined vertices shortest path, thereby using k to update the other vertex distance; such as, (s, V) the distance may be greater than (s, k) + (k, v) a distance
④ . Repeat steps (2) and (3) , until all vertices been traversed.
3. Design
1, Floyd algorithm
for (int i = 1; i <= n; i++) { for (int k = 1; k <= n; k++) { for (int j = 1; j <= n; j++) { p[k][j] = min(p[k][j], p[k][i] + p[i][j]);//松弛操作 } } }
2, Dijkstra algorithm
the while (queue not empty) {
int DIS A = team head, b = X team head;
for (side connected to the point b) {
IF (W + A < DIS [to]) {
DIS [to] = W + A;
(DIS [to], to) enqueue;
}
}
}
4. Analysis
1, no doubt, Floyd time complexity is O (n- ³ ) , this algorithm has advantages and disadvantages, of course, is a disadvantage of complexity is too high, the efficiency is too slow; the advantage of easy interrogation, each query complexity is O (1) . It pretreated shortest distance between each of all the points.
2, Dijkstra complexity easily calculated, Common complexity is O (n- ² ) , optimization point is how to remove from the set of nearest point, I used rootlets stack can O (1) taken out nearest points, update operation requires O (logN) , summary, the complexity of the stack is optimized O (nlogn) .
5. Source
1、Floyd
/*
author: keke
project name:Floyd算法
Time Complexity: O(n³)
*/
#include<bits/stdc++.h>
using namespace std;
#define pi acos(-1.0)
#define inf 0x3f3f3f3f
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
int mo[4][2] = { -1,0,1,0,0,-1,0,1 };
//int mo[8][2] = { -1,0,1,0,-1,-1,1,1,0,-1,0,1,1,-1,-1,1 };
const int maxn = 110;
ll n, m, is, t, ans, p[maxn][maxn], a, b, c;
int main() {
#ifdef ONLINE_JUDGE
#else
//freopen("input.txt", "r", stdin);
#endif
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cout << fixed << setprecision(2);
while (cin >> n >> m) {
for (int i = 1; i <= n; i++) {
for (int k = 1; k <= n; k++) {
if (i == k)p[i][k] = 0;
else p[i][k] = 1e18;
}
}
for (int i = 1; i <= m; i++) {
cin >> a >> b >> c;
p[a][b] = p[b][a] = min(c, p[a][b]);//二维矩阵存图
}
for (int i = 1; i <= n; i++) {
for (int k = 1; k <= n; k++) {
for (int j = 1; j <= n; j++) {
p[k][j] = min(p[k][j], p[k][i] + p[i][j]);//松弛操作
}
}
}
cin >> a >> b;
if (p[a][b] == 1e18)cout << "No path" << "\n";
else cout << p[a][b] << "\n";
}
return 0;
//good job!
}
2、Dijkstra
/*
author: keke
project name:Dijkstra算法(堆优化)
Time Complexity: O(nlog(n))
*/
#include<bits/stdc++.h>
using namespace std;
#define pi acos(-1.0)
#define inf 0x3f3f3f3f
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
int mo[4][2] = { -1,0,1,0,0,-1,0,1 };
//int mo[8][2] = { -1,0,1,0,-1,-1,1,1,0,-1,0,1,1,-1,-1,1 };
const int maxn = 110;
int n, m, is, t, ans, cnt, head[maxn], a, b, c, dis[maxn];
bool vis[maxn];
struct xx {
int t, next, w;
}xx[maxn << 1];
void add(int a, int b, int c) {//链式前向星
xx[cnt].next = head[a];
xx[cnt].t = b;
xx[cnt].w = c;
head[a] = cnt++;
}
void solve(int x, int y) {
memset(vis, false, sizeof(vis));
for (int i = 1; i <= n; i++)dis[i] = inf;
priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > q;
while (!q.empty())q.pop();
dis[x] = 0;
q.push(make_pair(0, x));//采用堆优化
while (!q.empty()) {
int a = q.top().first, b = q.top().second;
q.pop();
if (vis[b])continue;
vis[b] = true;
for (int i = head[b]; ~i; i = xx[i].next) {
int to = xx[i].t;
if (xx[i].w + a < dis[to]) {//松弛操作
dis[to] = a + xx[i].w;
q.push(make_pair(dis[to], to));
}
}
}
if (dis[y] == inf)cout << "No path" << "\n";
else cout << dis[y] << "\n";
}
int main() {
#ifdef ONLINE_JUDGE
#else
//freopen("input.txt", "r", stdin);
#endif
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cout << fixed << setprecision(2);
while (cin >> n >> m) {
cnt = 0;
memset(head, -1, sizeof(head));
for (int i = 1; i <= m; i++) {
cin >> a >> b >> c;
add(a, b, c);
add(b, a, c);
}
cin >> a >> b;
solve(a, b);
}
return 0;
//good job!
}