写在前面的话
ABC257-D 一道经典的Floyd,某选手使用了Dijkstra于是:
青青草原 ——> 五彩缤纷
棕色 red_L(CSDN账号) ——> 灰色red_L(AtCoder账号)
所以,为了避免上述悲剧,特地做Floyd算法详解一篇。
代码&&解析
代码
#include <iostream>
using namespace std;
const int N = 210, INF = 1e9;
int n, m;
int g[N][N];
void Floyd()
{
for(int k = 1; k <= n; k++) //考虑点k的加入
{
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++) //对从i ~ j的路径的影响
{
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]); //松弛
}
}
}
}
int main()
{
cin >> n >> m;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
if(i == j) g[i][j] = 0; //判断是否为自环
else g[i][j] = INF;
}
}
while(m--) //输入边长,并更新
{
int i, j, w;
cin >> i >> j >> w;
g[i][j] = min(g[i][j], w);
}
Floyd();
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
if(dist[i][j] > INF / 2) cout << "1e9" << endl;
else cout << dist[i][j] << endl;
}
}
return 0;
}
大概就是这样了。
解析
emmmmmm
感觉这个难度没啥好讲的
就是那个INF / 2
可能有人看不懂,讲一下。
这张图可能存在负权回路,所以dist[i][j]
可能小于INF
但是其表示的依然是正无穷,故需除以二。
(INF的实际大小需根据题目的数据范围考虑)
尾声
祝red_L(洛谷账号)早日棕名!!!
特别鸣谢red_L(Gitee账号)牺牲自我为我们造梗