• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

  • 联系
  • 订阅
  • 管理

View Post

最小生成树 HDU 1233 还是畅通工程

学会了并查集,kruskal算法就没有大问题了

先对边的权值排序, 再不断添加边(要保证不形成回路,用并查集),直到添加的边数为n-1时停止

 

这题WA几次,检查几次算法发现无问题,最后发现数组开少了,囧~

 

#include<iostream>
#include <algorithm>
#define  MAX 105
using namespace std;


struct Edge
{
	int v;
	int w; 
	int lenth;
};
int parent[MAX];


int find(int );
void Union(int , int);

bool cmp( Edge a, Edge b);

int main()
{
	int n, num, count,m;
	Edge edge[50*99+5];
	int root_a, root_b;
	int total_len;

	
	while (cin >> n && n)
	{	
		count = 1;
		total_len = 0;
		num = n*(n-1)/2;
		m = 0;

		memset(parent, -1, sizeof(int)*MAX);

		for (int i = 0; i < num; i++)	
			scanf("%d%d%d", &edge[i].v, &edge[i].w,  &edge[i].lenth);


		sort(edge, edge+num, cmp);

		//kruskal算法
		while (count < n)
		{
			root_a = find(edge[m].v-1);
			root_b = find(edge[m].w-1);
			if (root_a != root_b)
			{
				Union(root_a, root_b);
				total_len += edge[m].lenth; 
				count++;
			}
			m++;
		}

		cout << total_len << endl;
	}
	return 0;
}

bool cmp(Edge a, Edge b)
{
	return a.lenth < b.lenth;
}


int find(int i)
{
	int root, trail, lead;
	for (root = i; parent[root] >= 0; root = parent[root]);

	for (trail = i; trail != root; trail = lead)
	{
		lead = parent[trail];
		parent[trail] = root;
	}

	return root;
}

void Union(int i , int j)
{
	int temp = parent[i] + parent[j];

	if (parent[i] > parent[j])
	{
		parent[i] = j;
		parent[j] = temp;
	}
	else
	{
		parent[j] = i;
		parent[i] = temp;
	}
}

posted on 2010-10-16 19:12  sysuwhj  阅读(340)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3