HDU 2544 最短路
Posted jpphy0
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 2544 最短路相关的知识,希望对你有一定的参考价值。
链接
最短路 - http://acm.hdu.edu.cn/showproblem.php?pid=2544
分析
Floyd 1
- 设路径: 3 → 4 → 7 → 8 → 5 3\\rightarrow4\\rightarrow7\\rightarrow8\\rightarrow5 3→4→7→8→5 是(3,5)的最短路径,则有
- 路径上任取两点,这两点间的路径是这两点的最短路径
- 所有路径上的顶点的任意排列作为遍历的序,按Floyd的三重循环算法,能得到所有的最短路径。例如:遍历序为:8,7,4,5,3,则依次得到:
- (7,5);
- (4,8)、(4,5);
- (8,5)、(7,5)、(4,5);
- (3,4)、(3,7)、(3,8)、(3,5)。
Floyd 2
- 设前 i i i个顶点 1 、 2 、 … 、 i 1、2、…、i 1、2、…、i 间的最短距离已知(不考虑第 i + 1 , … 、 N i+1,…、N i+1,…、N个顶点对距离的影响)
- 第
i
+
1
i+1
i+1个顶点的影响是增加了一些过
i
+
1
i+1
i+1的路径,且新增路径可分为
i
+
1
i+1
i+1是或不是端点两类,即:
- ( i + 1 , 1 ) 、 ( i + 1 , 2 ) 、 … 、 ( i + 1 , i ) (i+1,1)、(i+1,2)、…、(i+1,i) (i+1,1)、(i+1,2)、…、(i+1,i)
- ( 1 , i + 1 , 2 ) 、 ( 1 , i + 1 , 3 ) 、 … 、 ( 1 , i + 1 , i ) (1,i+1,2)、(1,i+1,3)、…、(1,i+1,i) (1,i+1,2)、(1,i+1,3)、…、(1,i+1,i)
- ( 2 , i + 1 , 3 ) 、 ( 2 , i + 1 , 4 ) 、 … 、 ( 2 , i + 1 , i ) (2,i+1,3)、(2,i+1,4)、…、(2,i+1,i) (2,i+1,3)、(2,i+1,4)、…、(2,i+1,i)
- … … …
- ( i − 1 , i + 1 , i ) (i-1,i+1,i) (i−1,i+1,i)
- 分别处理上述增加的路径
代码
Floyd 1
floyd_1 —【O(n3),31MS】
// hdu 2544 最短路
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define MXN 110
int N, M, g[MXN][MXN];
int main(){
int a, b, c;
while(scanf("%d%d", &N, &M)){
if(N == 0 && M == 0) break;
memset(g, inf, sizeof g);
for(int i = 1; i <= M; ++i){
scanf("%d%d%d", &a, &b, &c);
g[a][b] = min(g[a][b], c);
g[b][a] = g[a][b];
}
for(int i = 1; i <= N; ++i){
for(int j = 1; j <= N; ++j){
if(g[j][i] == inf) continue;
for(int k = 1; k <= N; ++k){
g[k][i] = min(g[k][i], g[j][i]+g[j][k]);
g[i][k] = g[k][i];
}
}
}
printf("%d\\n", g[1][N]);
}
return 0;
}
Floyd 2
floyd_2 —【O(n3),31MS】
// hdu 2544 最短路
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define MXN 110
int N, M, g[MXN][MXN];
int main(){
int a, b, c;
while(scanf("%d%d", &N, &M)){
if(N == 0 && M == 0) break;
memset(g, inf, sizeof g);
for(int i = 1; i <= M; ++i){
scanf("%d%d%d", &a, &b, &c);
g[a][b] = min(g[a][b], c);
g[b][a] = g[a][b];
}
for(int i = 1; i <= N; ++i){
g[i][i] = 0;
// i与j连通的(i,k)最短距离
for(int j = 1; j < i; ++j){
if(g[j][i] == inf) continue;
for(int k = 1; k < i; ++k){
if(g[j][k] == inf) continue;
g[k][i] = min(g[k][i], g[j][i]+g[j][k]);
g[i][k] = g[k][i];
}
}
// 过i的(j,k)最短距离
for(int j = 1; j < i; ++j){
for(int k = 1; k < i; ++k){
if(g[i][k] == inf || g[j][i] == inf) continue;
g[j][k] = min(g[j][k], g[j][i]+g[i][k]);
g[k][j] = g[j][k];
}
}
}
printf("%d\\n", g[1][N]);
}
return 0;
}
Bellman-Ford
Bellman-Ford【O(n*m),15MS】
// hdu 2544 最短路
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define MXN 110
#define MXM 10010
int N, M, dis[MXN], u[MXM], v[MXM], w[MXM];
int main(){
int a, b, c;
while(scanf("%d%d", &N, &M)){
if(N == 0 && M == 0) break;
memset(dis, inf, sizeof dis);
dis[1] = 0;
for(int i = 1; i <= M; ++i) scanf("%d%d%d", u+i, v+i, w+i);
for(int i = 1; i <= N; ++i){
for(int j = 1; j <= M; ++j){
if(dis[u[j]] > w[j]+dis[v[j]]) dis[u[j]] = w[j]+dis[v[j]];
if(dis[v[j]] > w[j]+dis[u[j]]) dis[v[j]] = w[j]+dis[u[j]];
}
}
printf("%d\\n", dis[N]);
}
return 0;
}
以上是关于HDU 2544 最短路的主要内容,如果未能解决你的问题,请参考以下文章