AcWing 344. 觀光之旅 && 無向圖的最小環

題目鏈接:傳送門

無向圖最小環,floyed來求
普通的鬆弛操作還是有,就是f[i][j]f[i][j]表示從iijj的最短路
題目要求一個最小的環,存下一開始邊的大小d[i][j]d[i][j]
用中轉點k,d[i][j],f[i][j]k,d[i][j],f[i][j]來更新答案,d[i][k]+d[k][j]+f[i][j]d[i][k]+d[k][j]+f[i][j]就是這個最小的環,因爲f[i][j]f[i][j]求出的最小的路徑不經過kk
題目還要求輸出路徑,再用一個數組記錄每個點的後面節點,要跟着ff一起更新,再一個vectorvector記錄路徑即可

#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 << " ";
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章