POJ 1679 The Unique MST (Secondly Small Spanning Tree)

Question: See if the minimum spanning tree is unique.

Solution: The second-smallest spanning tree.
Many schools have been beaten as autistic, so let's brush up on the question of kuangbin.

First find mst, then directly enumerate all edges not in mst, replace the edge with the largest edge weight, and update the answer.

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<fstream>
#include<set>
#include<map>
#include<sstream>
#include<iomanip>
#define ll long long
using namespace std;
/*
 * 次小生成树
 * 求最小生成树时,用数组 Max[i][j] 来表示 MST 中 i 到 j 最大边权
 * 求完后,直接枚举所有不在 MST 中的边,替换掉最大边权的边,更新答案
 * 点的编号从 0 开始
 */
const int MAXN = 110;
const int INF = 0x3f3f3f3f;
bool vis[MAXN], used[MAXN][MAXN];
int lowc[MAXN], pre[MAXN], cost[MAXN][MAXN];
int Max[MAXN][MAXN];//Max[i][j] 表示在最小生成树中从 i 到 j 的路径中的最大边权
int Prim(int n) {
    
    
	int ans = 0;
	memset(vis, false, sizeof(vis));
	memset(Max, 0, sizeof(Max));
	memset(used, false, sizeof(used));
	vis[0] = true;
	pre[0] = -1;
	for (int i = 1; i < n; i++) {
    
    
		lowc[i] = cost[0][i];
		pre[i] = 0;
	}
	lowc[0] = 0;
	for (int i = 1; i < n; i++) {
    
    
		int minc = INF;
		int p = -1;
		for (int j = 0; j < n; j++)
			if (!vis[j] && minc > lowc[j]) {
    
    
				minc = lowc[j];
				p = j;
			}
		if (minc == INF)return -1;
		ans += minc;
		vis[p] = true;
		used[p][pre[p]] = used[pre[p]][p] = true;
		for (int j = 0; j < n; j++) {
    
    
			if (vis[j] && j != p)Max[j][p] = Max[p][j] = max(Max[j][pre[p]], lowc[p]);
			if (!vis[j] && lowc[j] > cost[p][j]) {
    
    
				lowc[j] = cost[p][j];
				pre[j] = p;
			}
		}
	}
	return ans;
}
int t, n, m;
int main() {
    
    
	scanf("%d", &t);
	while (t--) {
    
    
		memset(cost, 0x3f, sizeof(cost));
		scanf("%d%d", &n, &m);
		for (int i = 1; i <= m; i++) {
    
    
			int u, v, w;
			scanf("%d%d%d", &u, &v, &w); u--, v--;
			cost[u][v] = w;
			cost[v][u] = w;
		}
		int ans = Prim(n);
		int ans2 = INF;
		for (int i = 0; i < n; i++) {
    
    
			for (int j = 0; j < n; j++) {
    
    
				if (i == j || used[i][j]) continue;
				ans2 = min(ans2, ans + cost[i][j] - Max[i][j]);
			}
		}
		if (ans == ans2) puts("Not Unique!");
		else printf("%d\n", ans);
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/qq_43680965/article/details/107799386