最短路径 单源最短路径Dijkstra(迪杰斯特拉)算法 Floyd(弗洛伊德)算法

版权声明:未经允许禁止转载。转载请联系我WX:yuyi5453。并且注明出处 https://blog.csdn.net/weixin_40532377/article/details/83684876

题目链接:https://nanti.jisuanke.com/t/230

两个算法的主要思想都是松弛,就是两点间的距离通过第三点来变短

比如   1->3=10     1->2=2   2->3=5    这样你就可以通过2号点把1,3两点的距离缩短为7

Dijkstra算法被称为单源最短路,意思就是只能计算某个点到其他点的最短路,而Floyd算法

可以计算各个点之间的最短路径。

举个例子:有1~6  6个点   Dijkstra只能计算1号(或者2、3....其中某一个)点到其他点的最短路径

而Floyd算法就可以直接把1->2   1->3 .......任意两点之间的最短路都算出来

当然Floyd的时间复杂度是比Dijkstra高的。

首先来看Floyd算法

for (k=1;k<=n;k++)
	for (i=1;i<=n;i++)
		for (j=1;j<=n;j++)
			if (e[i][j]>e[i][k]+e[k][j])
			e[i][j]=e[i][k]+e[k][j];

使用K点对i,j两点进行缩短(松弛),当从 i 到 k 再从 k 到 j 的距离小于从 i 直接到 k 的距离是 i 到 j 的距离就被缩短。

最终的图就是一个全部为最短路的图

再看Dijkstra算法  

首先来解释一下什么叫源,源其实就是起点,你想从哪一个点开始走的点。

单源最短就是单单这个点和其他各点的最短路。

因为是单源的所以我们就不必要设置一个二维数组,可以设置一个一位数组dis[],dis[i]表示的就是

源点到 i 的最短路径。

先上代码: 

void dijkstra(){
	bool book[maxn];
	memset(book,0,sizeof(book));
	int m;
	for(int i=1;i<T;i++){
		int min=INF;
		for(int j=1;j<=T;j++){
			if(!book[j] && dis[j]<min){
				min=dis[j];
				m=j;
			}
		}
		book[m]=true;
		for(int k=1;k<=T;k++){
			if(dis[k]>dis[m]+e[m][k]) dis[k]=dis[m]+e[m][k];
		}
	}
	
}

主要思想就是:先找到一个和源点最近的点,这个点和源点之间肯定是最短路了(因为不可能通过第三个点进行松弛了(负权除外)),标记这个点已经找到它到源点最短路,然后通过这个点对其他各个点进行松弛。重复上述步骤,知道标记完所有的点。

题目的代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2505;
const int INF = 99999;
int e[maxn][maxn];
int T,C,Ts,Te;
int u,v,c;
int dis[maxn];
void init(){
	cin>>T>>C>>Ts>>Te;
	
	for(int i=1;i<=T;i++){
		for(int j=1;j<=T;j++){
			e[i][j]=INF;
		}
	}
	for(int i=1;i<=T;i++){
		e[i][i]=0;
	}
	
	for(int i=0;i<C;i++){
		scanf("%d%d%d",&u,&v,&c);
		e[v][u]=e[u][v]=c;
	}
	
	for(int i=1;i<=T;i++){
		dis[i]=e[Ts][i];
	}
}

void dijkstra(){
	bool book[maxn];
	memset(book,0,sizeof(book));
	int m;
	for(int i=1;i<T;i++){
		int min=INF;
		for(int j=1;j<=T;j++){
			if(!book[j] && dis[j]<min){
				min=dis[j];
				m=j;
			}
		}
		book[m]=true;
		for(int k=1;k<=T;k++){
			if(dis[k]>dis[m]+e[m][k]) dis[k]=dis[m]+e[m][k];
		}
	}
	
}
int main()
{
	init();
	dijkstra();
	cout<<dis[Te];
 } 

                                                                                             完活!

猜你喜欢

转载自blog.csdn.net/weixin_40532377/article/details/83684876