Floyd-多源最短路径

今天抽个时间复习一下Floyd——多源最短路径
所谓“多源”就是求出每个点到另外所有点的最短距离,所以说比不上迪杰斯特拉的速度,时间复杂度也是到了O(n^3)。
不过写起来就很简单,核心就五行代码,而且也容易理解。
就比如说给了如下数据

在这个图中,没有给权重的边先看成正无穷,想要求i点到j点的最短距离就是看看能不能通过寻找中间点k使得i到k的距离加上k到j的距离小于i到j的距离。
即:

if(v[i][j]>v[i][k]+v[k][j])
{
    v[i][j]=v[i][k]+v[k][j];
}

如上图1到5的距离是100,当中间点为2时,100>1+80,这个时候v[1][5]就会更新为81;
所以说更新所有点就是要在判断条件外面加两个循环,然后把中间点所有情况也考虑一遍就要再加一个循环。
所以核心代码就下面五行。

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

但是不能解决带负权回路的图,这样就找不到最小距离。

下面给完整代码和测试用例

#include<bits/stdc++.h>
using namespace std;
int v[505][505];
#define inf 99999;
int main()
{
	int n,m,t1,t2,t3;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	if(i==j)v[i][j]=0;
	else
	v[i][j]=inf;
	for(int i=0;i<m;i++)
	{
	    cin>>t1>>t2>>t3;
	    v[t1][t2]=v[t2][t1]=t3;
	}
	
	for(int k=1;k<=n;k++)
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	if(v[i][j]>v[i][k]+v[k][j])
	v[i][j]=v[i][k]+v[k][j];
	
	cout<<endl<<endl;
	for(int i=1;i<=n;i++)
	{
	    for(int j=1;j<=n;j++)
	    printf("%-5d",v[i][j]);
	    cout<<endl;
	}
	return 0;
}

6 11
3 4 70
1 2 1
5 4 50
2 6 50
5 6 60
1 3 70
4 6 60
3 6 80
5 1 100
2 4 60
5 2 80

这里因为我用的是无向图所以数据是对称的。

posted @ 2022-03-29 15:47  f_string  阅读(147)  评论(0编辑  收藏  举报