图论-最短路Floyd算法

发布于:2025-08-04 ⋅ 阅读:(13) ⋅ 点赞:(0)

Floyd(弗洛依德)算法

动态规划算法,也称插点法。是全源最短路算法。
状态表示
d[k,i,j]表示从i到j,且中间只经过节点编号1~k的最短路径的长度。
状态计算
路径的选择分两种:

  • 1.路径不经过k点,继承原值:d[k,i,j]=d[k-1,i,j]
  • 2.路径经过k点,松弛操作d[k,i,j]=d[k-1,i,k]+d[k-1,k,j]

代码展示

void fioyd()
{
	for(int k=1;k<=n;k++)
	{
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
			}
		}
	}
}

!!!
K一定要在最外层
k放在内层会出错。
因为该算法是通过递归,必须将k-1层的所有状态计算出来后才能得到第k层的值。
不管路径经不经过k点,计算都与k无关,可以省去第一维
初始化时:

  • 如果i,j两点间无边直接相连,d[i][j]初始化为无穷大
  • 如果有边,d[i][j]就是二者边权。
  • i=j,自身到自身的距离为0,d[i][j]=0。

枚举完n层后,所有的最短路都会被找出来了。

路径记录与输出

void path(int x,int y)
{
	if(p[x][y]==0)return ;
	int k=p[x][y];//x.y之间的最短路
	path(x,k);
	cout<<k<<" ";
	path(k,y); 
 } 

完整代码

int d[N][N],p[N][N];
void fioyd()
{
	for(int k=1;k<=n;k++)
	{
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				if(d[i][j]>d[i][k]+d[k][j])
				{
					d[i][j]=d[i][k]+d[k][j];
					p[i][j]=k; 
				}
			}
		}
	}
}
void path(int x,int y)
{
	if(p[x][y]==0)return ;
	int k=p[x][y];
	path(x,k);
	cout<<k<<" ";
	path(k,y); 
 } 
floyd()
 {
 	cin>>a>>b;
 	cout<<a<<" ";
 	path(a,b);
 	cout<<b<<" ";
 }

时间复杂度:O( n 3 n^3 n3)


网站公告

今日签到

点亮在社区的每一天
去签到