Floyd

参考:​​Floyd 算法​​​ ​​第一篇Floyed题解​

模板题:​​寻宝之路Clear And Present Danger​​​ ​​牛栏Cow Hurdles​

Floyd的思路:首先 \(f[i][j]\) 表示的是 \(i\) 到 \(j\) 的最短路径的长度, \(f[i][j]\)初始化的时候,如果 \(i\) 和 \(j\) 有一条直接相连的边,长为 \(w\) ,那么就让 \(f[i][j]=w\) 而\(i\) 到 \(j\) 的路径在经过了某个不知名的 \(k\) 点之后而变短了,那么我们现在就需要枚举每一个 \(k\) 点对所有的 \(i\) 和 \(j\) 可能产生的作用,具体实现为\(f[i][j]=min(f[i][j],f[i][k]+f[k][j])\),\(k,i,j\) 都从\(1\)~\(n\)开始遍历

​寻宝之路Clear And Present Danger​​:

// Created by CAD on 2019/8/18.
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
const int maxn=1e5+5;
ll a[maxn],f[105][105];
int main()
{
int n,m; cin>>n>>m;
for(int i=1;i<=m;++i) cin>>a[i];
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
cin>>f[i][j];
for(int k=1;k<=n;++k)
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
ll ans=0;
for(int i=1;i<m;++i)
ans+=f[a[i]][a[i+1]];
cout<<ans<<endl;
}

​牛栏Cow Hurdles​​:

// Created by CAD on 2019/8/19.
#include <bits/stdc++.h>
#define test(n) cout<<n<<endl
using namespace std;
using ll=long long;
int f[305][305];
int G[305][305];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n,m,t;
cin>>n>>m>>t;
for(int i=1,s,e,w;i<=m;++i)
cin>>s>>e>>w,G[s][e]=f[s][e]=w;
for(int k=1;k<=n;++k)
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
if((!f[i][j])&&f[i][k]&&f[k][j]) f[i][j]=max(f[i][k],f[k][j]);
else if(f[i][k]&&f[k][j])
f[i][j]=min(f[i][j],max(f[i][k],f[k][j]));
while(t--)
{
int s,e; cin>>s>>e;
if(!f[s][e]) test(-1);
else test(f[s][e]);
}
return 0;
}

CAD加油!欢迎跟我一起讨论学习算法,