題目鏈接:傳送門
無向圖最小環,floyed來求
普通的鬆弛操作還是有,就是表示從到的最短路
題目要求一個最小的環,存下一開始邊的大小
用中轉點來更新答案,就是這個最小的環,因爲求出的最小的路徑不經過
題目還要求輸出路徑,再用一個數組記錄每個點的後面節點,要跟着一起更新,再一個記錄路徑即可
#include <bits/stdc++.h>
#define A 110
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f / 2;
int n, m, a, b, c, d[A][A], f[A][A], ans = inf, nxt[A][A];
vector<int> v;
int main(int argc, char const *argv[]) {
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
d[i][j] = f[i][j] = inf;
for (int i = 1; i <= m; i++) {
scanf("%d%d%d", &a, &b, &c);
d[a][b] = d[b][a] = f[a][b] = f[b][a] = min(d[a][b], c);
nxt[a][b] = b; nxt[b][a] = a;
}
for (int k = 1; k <= n; k++) {
for (int i = 1; i <= n; i++)
for (int j = i + 1; j <= n; j++)
if (ans > d[i][k] + d[k][j] + f[i][j]) {
ans = d[i][k] + d[k][j] + f[i][j];
v.clear();
for (int fr = i; fr != j; fr = nxt[fr][j]) v.push_back(fr);
v.push_back(j); v.push_back(k);
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
if (i != j and j != k and f[i][j] > f[i][k] + f[k][j])
f[i][j] = f[i][k] + f[k][j], nxt[i][j] = nxt[i][k];
}
if (ans == inf) puts("No solution.");
else for (auto i : v) cout << i << " ";
}