floyd算法
#include <bits/stdc++.h>
using namespace std;
#define io std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define x first
#define y second
#define fr front
#define db double
//int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
//int dx[8] = {-1, -1, -1, 0, 1, 1, 1, 0};
//int dy[8] = {-1, 0, 1, 1, 1, 0, -1, -1};
//int dx[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
//int dy[8] = {1, 2, 2, 1, -1, -2, -2, -1};
typedef pair<int, int> PII;
typedef long long LL ;
const int N = 110, INF = 0x3f3f3f3f;
//
int g[N][N], d[N][N]; // g记录原始的 2 点之间的距离( A -> K , K -> B ), d 记录 更新之后 的 A -> B
int p[N][N];
int path[N], cnt;
int n, m;
void get_path(int x, int y)
{
if (p[x][y] == 0) return ;
get_path( x, p[x][y]);
path[cnt ++ ] = p[x][y];
get_path(p[x][y], y);
}
int main()
{
io;
cin >> n >> m;
memset(g, 0x3f, sizeof g);
for (int i = 1;i <= n;i ++ ) g[i][i] = 0;
while (m -- )
{
int a, b, c;
cin >> a >> b >> c;
g[a][b] = g[b][a] = min(g[a][b], c);
}
int ans = INF;
memcpy(d, g, sizeof g); // g 留做备份
for (int k = 1;k <= n;k ++ ) // 设 k 为 路线中节点的最大编号
{
for (int i = 1;i < k;i ++ )
{
// cout << ans << endl;
for (int j = i + 1;j < k;j ++ )
{
//cout << ans << endl;
//d[j][i]则表示j到i且经过的节点编号小于k,因为在环中k就是最大的,只能经过小于k的节点了;
if ((LL)g[i][k] + g[k][j] + d[i][j] < ans) // g[i][k] 与 g[k][j] 是两点之间的距离 题目要求环 点数 >= 3
{
// i -> k -> j - > i
//cout << ans << endl;
ans = g[i][k] + g[k][j] + d[i][j];
cnt = 0;
path[cnt ++ ] = k;
path[cnt ++ ] = i;
get_path(i, j);
path[cnt++] = j;
}
}
}
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; // 由 k 点转移
}
}
if (ans == INF) cout << "No solution.";
else for (int i = 0;i < cnt;i ++ ) cout << path[i] << ' ';
return 0;
}