题目传送门
Floyd,每当处理到一个断点k时,更新答案,用此时的所有任选两个点(除了k外)的最短路和到k的距离更新答案,因为此时的最短路一定不包括k,可以满足环的要求.
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long n,m,g[101][101],dp[101][101],ans = 2099999999;
int main() {
scanf("%lld%lld",&n,&m);
memset(g,0xf,sizeof(g));
memset(dp,0xf,sizeof(dp));
for(int i = 1;i <= m; i++) {
long long x,y,z;
scanf("%lld%lld%lld",&x,&y,&z);
dp[x][y] = dp[y][x] = g[x][y] = g[y][x] = min(z,g[y][x]);
}
for(int k = 1;k <= n; k++) {
for(int i = 1;i < k; i++)//为什么到k-1就可以了呢?因为在以后的更新中一定会用到k~n的情况
for(int j = i + 1;j < k; j++)
if(i != j && j != k && i != k)
ans = min(ans,g[i][k] + g[k][j] + dp[i][j]);
for(int i = 1;i <= n; i++)
for(int j = 1;j <= n; j++)
if(i != j && j != k && i != k)
dp[j][i] = dp[i][j] = min(dp[i][j],dp[i][k] + dp[k][j]);
}
if(ans < 1000000000)
printf("%lld",ans);
else printf("No solution.");
return 0;
}