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 34785 是(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 12i 间的最短距离已知(不考虑第 i + 1 , … 、 N i+1,…、N i+1N个顶点对距离的影响)
  • 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+11)(i+12)(i+1i)
    • ( 1 , i + 1 , 2 ) 、 ( 1 , i + 1 , 3 ) 、 … 、 ( 1 , i + 1 , i ) (1,i+1,2)、(1,i+1,3)、…、(1,i+1,i) (1i+12)(1i+13)(1i+1i)
    • ( 2 , i + 1 , 3 ) 、 ( 2 , i + 1 , 4 ) 、 … 、 ( 2 , i + 1 , i ) (2,i+1,3)、(2,i+1,4)、…、(2,i+1,i) (2i+13)(2i+14)(2i+1i)
    • … …
    • ( i − 1 , i + 1 , i ) (i-1,i+1,i) (i1i+1i)
  • 分别处理上述增加的路径

代码

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 最短路的主要内容,如果未能解决你的问题,请参考以下文章

hdu 2544 最短路

hdu 2544 最短路

HDU 2544 - 最短路 - [堆优化dijkstra][最短路模板题]

HDU 2544最短路 (迪杰斯特拉算法)

hdu2544---最短路

HDU-2544-最短路