最小生成树 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;

	}

}

你可能感兴趣的:(最小生成树)