Floyd算法和Dijkstra算法

1.问题

Ployd算法求多源最短路径问题
Dijkstra算法求单源最短路径问题

2.解析

Ployd算法求多源最短路径问题
Dk [i][j] = 路径{ i -> { i<=k }->j }的最小长度,D0, D1, …, D|V|-1 [i][j]即给出了i到j的真正最短距离,当Dk-1已经完成,递推到Dk时:或者k不属于最短路径{ i->{ i<=k }->j },则Dk = Dk-1,或者k∈最短路径{ i->{ i<= k }->j },则该路径必定由两段最短路径组成: Dk [i][j]=Dk-1 [i][k]+Dk-1[k][j]

Dijkstra算法求单源最短路径问题
贪婪算法,通过取最小值来更新最短路径数组来完成单源最短路径问题

3.设计

//ployd
#include<iostream>
using namespace std;
#define Vmax 10
int main() {
	int a[Vmax][Vmax] = {0}, i, j, k;
	int V, E, x, y, z;
	cout << "输入点的个数和边的个数:";
	cin >> V >> E;
	cout << "输入两个点和他们的距离:" << endl;
	for (i = 0; i < E; i++) {
		cin >> x >> y >> z;
		a[x][y] = z;
	}
	for (i = 1; i < V+1; i++) {
		for (j = 1; j < V+1; j++) {
			if (a[i][j] == 0 && i != j)
				a[i][j] = 100000;
		}
	}
	for (k = 1; k < V + 1; k++) {
		for (i = 1; i < V + 1; i++) {
			for (j = 1; j < V + 1; j++) {
				if (a[i][k] + a[k][j] < a[i][j]) {
					a[i][j] = a[i][k] + a[k][j];
				}
			}
		}
	}
	for (i = 1; i < V + 1; i++) {
		for (j = 1; j < V + 1; j++) {
			cout << a[i][j] << " ";
			if (j == V) {
				cout << endl;
			}
		}
	}
	return 0;
}
/*测试用例
6 8
1 2 2
1 3 6
1 4 4
2 3 3
3 1 7
3 4 1
4 1 5
4 3 12
结果
0 2 5 4
9 0 3 4
6 8 0 1
5 7 10 0*/






//dijkstra
#include<iostream>
using namespace std;
#define Infinity 10000
#define moreInfinity 100000
#define matrixSize 10
bool isEmpty(int arr[],int V) {
	int i;
	for (i = 1; i < V + 1; i++) {
		if (arr[i] == 0) {
			return 0;
		}
	}
	return 1;
}
int main() {
	int V, E;
	int i, j;
	int x, y, z;
	int a[matrixSize][matrixSize], A[matrixSize];
	int min = moreInfinity, k, minn = moreInfinity;
	int v[matrixSize] = { 0 };
	cout << "输入点的个数和边的个数:";
	cin >> V >> E;
	cout << "输入两个点和他们的距离:" << endl;
	for (i = 0; i < V + 1; i++) {
		A[i] = 10000;
		for (j = 0; j < V + 1; j++) {
			a[i][j] = 10000;
		}
	}
	for (i = 0; i < E; i++) {
		cin >> x >> y >> z;
		a[x][y] = z;
	}
	for (i = 2; i < V + 1; i++) {
		if (a[1][i] != 10000) {
			A[i] = a[1][i];
		}
	}
	A[1] = 0;
	v[1] = 1;
	while(!isEmpty(v,V)) {
		min = moreInfinity;
		for (j = 1; j < V + 1; j++) {//找到最小点位置
			if (A[j] < min && A[j] != 10000 && v[j] != 1) {
				min = A[j];
				k = j;
			}
		}
		v[k] = 1;
		for (j = 1; j < V + 1; j++) {//更新一排数组
			if (a[k][j] != 10000) {
				if (min + a[k][j] < A[j]) {
					A[j] = min + a[k][j];
				}
			}
		}	
	}
	for (i = 1; i < V + 1; i++) {
		cout << A[i] << " ";
	}
	return 0;
}

//测试用例1
/*8 11
1 2 1
2 4 2
3 1 2
4 3 1
5 4 2
4 6 8
6 5 2
5 7 2
7 6 3
7 8 3
8 6 2*/
//结果1
//0 1 4 3 13 11 15 18


//测试用例2
/*6 9
1 2 1
1 3 12
2 3 9
2 4 3
4 3 4
3 5 5
4 5 13
5 6 4
4 6 15*/
//结果2
//0 1 8 4 13 17

4.分析

Ployd:O(n3) Dijkstra:O(n2)

5.源码

https://github.com/BeFlamingo/faming2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值