多元最短路(Floyd)

是一个基于动态规划的全源最短路算法。它可以高效地求出图上任意两点之间的最短路

时间复杂度 O(n^3)

状态转移方程

f[i][j]=min(f[i][j],f[i][k]+f[k][j])

核心代码 

void floyd(){
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				s[i][j]=min(s[i][j],s[i][k]+s[k][j]);
}
k就是一个中间值,每次把从i到j的距离与从i到k再从k到j的距离进行比较,选取最小值,做答案

多元最短路(Floyd)_第1张图片

 例如k等于1的时候可以更新4,2这个点k等于2的时候可以更新3,1这个点。。。。。。

例题B3647 【模板】Floyd 算法

给出一张由 n 个点 m 条边组成的无向图。

求出所有点对 (i,j) 之间的最短路径。

输入格式

第一行为两个整数 n,m,分别代表点的个数和边的条数。

接下来 m 行,每行三个整数 u,v,w,代表 u,v 之间存在一条边权为 w 的边。

输出格式

输出 n 行每行 n 个整数。

第 i 行的第 j 个整数代表从 i 到 j 的最短路径。

输入输出样例

输入 

4 4
1 2 1
2 3 1
3 4 1
4 1 1

输出 

0 1 2 1
1 0 1 2
2 1 0 1
1 2 1 0

说明/提示

对于 100% 的数据n≤100,m≤4500,任意一条边的权值 w 是正整数且 1⩽w⩽1000。

#include
using namespace std;
const int N=1e4,INF=1e9;
int s[N][N];     //用于存图
int n,m,q;

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

int main(){
	cin>>n>>m;
	//初始化
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)  
			if(i==j)s[i][j]==0;
			else s[i][j]=INF;     //s[i][j]代表从i到j的最短距离
			
	//把给的边存入
	while(m--){
		int a,b,c;
		cin>>a>>b>>c;
		s[a][b]=min(s[a][b],c);
		s[b][a]=min(s[b][a],c);    //可能给重复的值,取最小的那一个存入 
	} 
	
	floyd();
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++)
			cout<

 

你可能感兴趣的:(算法)