您的位置:首页 > 产品设计 > UI/UE

POJ 1679 The Unique MST

2012-11-23 11:19 225 查看
大意不再赘述。

思路:让你求次小生成树,我们可以枚举每一条边,之后删除在MST中的最大的一条边,然后保存最小值,这就是权值第二大的树,即次小生成树。

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
using namespace std;

const int MAXN = 110;
const int INF = 0x3f3f3f3f;

int w[MAXN][MAXN];
int path[MAXN][MAXN];
bool use[MAXN][MAXN];
int fa[MAXN];
int d[MAXN];

int n, m;
int cnt1, cnt2;

void init()
{
	cnt1 = cnt2 = 0;
	memset(w, INF, sizeof(w));
	memset(use, 0, sizeof(use));
}

void Prim(int src)
{
	bool vis[MAXN] = {0};
	for(int i = 1; i <= n; i++) d[i] = (i == src)? 0:INF;
	for(int i = 1; i <= n; i++) fa[i] = -1;
	for(int i = 1; i <= n; i++)
	{
		int x, m = INF;
		for(int y = 1; y <= n; y++) if(!vis[y] && m > d[y]) m = d[x=y];
		for(int y = 1; y <= n; y++) if(vis[y]) //扫描已经在MST中的边 
		{
			path[x][y] = path[y][x] = max(path[fa[x]][y], w[fa[x]][x]);
			//path[x][y] = path[y][x] = max(path[fa[x]][y], d[x]);
		}
		vis[x] = 1;
		use[fa[x]][x] = use[x][fa[x]] = 1; //标记在MST中 
		cnt1 += m;
		for(int y = 1; y <= n; y++) if(d[y] > w[x][y])
		{
			d[y] = w[x][y];
			fa[y] = x;
		}
	}
}

void SMST()
{
	for(int i = 1; i < n; i++)
	{
		for(int j = i+1; j <= n; j++) if(!use[i][j] && w[i][j] != INF)
		{
			cnt2 = cnt1 + w[i][j]-path[i][j]; //枚举每一条边 
			if(cnt1 == cnt2)
			{
				printf("Not Unique!\n");
				return ;
			}
		}
	}
	printf("%d\n", cnt1);
}

void read_case()
{
	init();
	scanf("%d%d", &n, &m);
	while(m--)
	{
		int u, v, cost;
		scanf("%d%d%d", &u, &v, &cost);
		w[u][v] = w[v][u] = cost;
	}
}

void solve()
{
	read_case();
	Prim(1);
	SMST();
}

int main()
{
	int T;
	scanf("%d", &T);
	while(T--)
	{
		solve();
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: