次最小生成树

参考链接

#include <stdio.h>
#include <string.h>
#include <algorithm>
#define N 105
#define INF 0xfffffff
using namespace std;
int G[N][N], used[N][N],path[N][N];
int pre[N], dis[N];
bool vis[N];
int m, n;
void init(){
	for(int i = 1; i <= n; i++){
		vis[i] = false;
//		dis[i] = INF;
		for(int j = 1; j <= n; j++)
			G[i][j] = INF;
	}
	memset(used, 0, sizeof(used));
	memset(path, 0, sizeof(path));
}
int Prim(int st){
	int sum = 0, Min;
	for(int i = 1; i <= n; i++){
		dis[i] = G[st][i];
		pre[i] = st;
	}
	dis[st] = 0;
	vis[st] = 1;
	for(int i = 1; i < n; i++){
		Min = INF;
		for(int j = 1; j <= n; j++){
			if(!vis[j] && Min > dis[j]){
				Min = dis[j];
				st = j;
			}
		}
		vis[st] = 1;
		sum += Min;
		used[st][pre[st]] = used[pre[st]][st] = 1;
		for(int j = 1; j <= n; j++){
			if(vis[j] && j != st)
				path[j][st] = path[st][j] = max(path[j][pre[st]], dis[st]);
			if(!vis[j] && dis[j] > G[st][j]){
				dis[j] = G[st][j];
				pre[j] = st;
			}
		}
	}
	return sum;
}
int sec_Prim(int tmp){
	int sum = INF;
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= n; j++){
			if(i != j && !used[i][j])
				sum = min(sum, tmp + G[i][j] - path[i][j]);
		}
	}
	return sum;
}
int main(){
	int t;
	int st, ed, len;
	scanf("%d", &t);
	while(t--){
		scanf("%d%d", &n, &m);
		init();
		for(int i = 0; i < m; i++){
			scanf("%d%d%d", &st, &ed, &len);
			G[st][ed] = G[ed][st] = len;
		}
		int ans1 = Prim(1);
		int ans2 = sec_Prim(ans1);
		if(ans1 != ans2)
			printf("%d\n", ans1);
		else
			puts("Not Unique!");
	}
	return 0;
}
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页