现在的位置: 首页 > 综合 > 正文

HDU 3道最小生成树题目

2012年09月27日 ⁄ 综合 ⁄ 共 3402字 ⁄ 字号 评论关闭
//hdu1879 还是畅通工程
#include <iostream>
#include <algorithm>
#define  MAX 5000
using namespace std;

int father[MAX];
int my_rank[MAX];

void make_set()
{
	for (int i = 0; i < MAX; i++)
	{
		my_rank[i] = 0;
		father[i] = i;
	}
}

int find_set(int x)
{
	if (x != father[x])
		father[x] = find_set(father[x]);

	return father[x];
}

void union_set(int x, int y)
{
	x = find_set(x);
	y = find_set(y);

	if (x == y) return;

	if (my_rank[x] > my_rank[y])
		father[y] = x;
	else
	{
		father[x] = y;
		if (my_rank[x] == my_rank[y])
			my_rank[y]++;
	}

}

struct edge
{
	int begin;
	int end;
	int weight;
};

int N,M;

edge e[MAX];

bool cmp(const edge& a, const edge& b)
{
	return a.weight < b.weight;
}

int main()
{
	int count, result;
	int x, y;
	bool isbuild;

	while (cin >> N && N)
	{
		M = N*(N-1)/2;
		make_set();

		for (int i = 0; i < M; i++)
		{
			cin >> e[i].begin >> e[i].end >> e[i].weight >> isbuild;
			if (isbuild)
			{
				x = find_set(e[i].begin);
				y = find_set(e[i].end);
				if (x != y)
					union_set(x, y);
			}
		}

		sort(e, e+M, cmp);
		count = 0;
		result = 0;

		while (count != M)
		{

			x = find_set(e[count].begin);
			y = find_set(e[count].end);

			if (x != y)
			{
				union_set(x, y);
				result += e[count].weight;
			}
			count++;
		}
		cout << result << endl;
	}
	return 0;
}
//1863畅通工程
#include<iostream>
#include <algorithm>
#define  MAX 105
using namespace std;

int father[MAX];
int my_rank[MAX];

void make_set()
{
	for (int i = 0; i < MAX; i++)
	{
		my_rank[i] = 0;
		father[i] = i;
	}
}

int find_set(int x)
{
	if (x != father[x])
		father[x] = find_set(father[x]);

	return father[x];
}

void union_set(int x, int y)
{
	x = find_set(x);
	y = find_set(y);

	if (x == y) return;

	if (my_rank[x] > my_rank[y])
		father[y] = x;
	else
	{
		father[x] = y;
		if (my_rank[x] == my_rank[y])
			my_rank[y]++;
	}

}

struct edge
{
	int begin;
	int end;
	int weight;
};

int N,M;

edge e[MAX];

bool cmp(const edge& a, const edge& b)
{
	return a.weight < b.weight;
}

int main()
{
	int count, result;
	int x, y;

	while (cin >> N && N)
	{
		cin >> M;
		for (int i = 0; i < N; i++)
			cin >> e[i].begin >> e[i].end >> e[i].weight;

		sort(e, e+N, cmp);

		count = 0;
		result = 0;

		make_set();
		while (count != N)
		{

			x = find_set(e[count].begin);
			y = find_set(e[count].end);

			if (x != y)
			{
				union_set(x, y);
				result += e[count].weight;
			}
			count++;
		}

		count = 0;
		for (int i = 1; i <= M; i++)
		{
			if (father[i] == i) count++;
		}

		if (count == 1)
			cout << result << endl;
		else
			cout << "?" << endl;

	}
	return 0;
}


//1875畅通工程再续
//这题注意精度问题,要先计算开根号的值,然后在最小生成树时在加起来
//不可先保存没开平方的值,一开始我保存的是没开根号,得到最后答案后再开根号,认为这会准确些
//后来WA卡住了,后来实际想不同就和别人解题报告一比,发现了这个问题
#include <iostream>
#include <algorithm>
#include <math.h>
#include <stdio.h>
#define MAX 6000
using namespace std;

int father[MAX];
int my_rank[MAX];

void make_set()
{
	for (int i = 0; i < MAX; i++)
	{
		father[i] = i;
		my_rank[i] = 0;
	}
}

int find_set(int x)
{
	if (x != father[x])
		father[x] = find_set(father[x]);

	return father[x];
}

void union_set(int x, int y)
{
	x = find_set(x);
	y = find_set(y);

	if (x == y) return;

	if (my_rank[x] > my_rank[y])
		father[y] = x;
	else
	{
		father[x] = y;

		if (my_rank[x] == my_rank[y])
			my_rank[y]++;
	}
}

struct coordinate
{
	int x, y;
	int id;
};

struct edge
{
	int begin_id;
	int end_id;
	double weight;
};

edge e[MAX];
coordinate point[MAX];

bool cmp(const edge& a, const edge& b)
{
	return a.weight < b.weight;
}

int main()
{
	int cases;
	int n;
	int count;
	double distances;

	cin >> cases;
	while (cases--)
	{
		cin >> n;

		for (int i = 0; i < n; point[i].id = i,i++)
			cin >> point[i].x >> point[i].y;

		count = 0;
		for (int i = 0; i < n; i++)
		{
			for (int j = i+1; j < n; j++)
			{
				distances = sqrt((double)((point[i].x-point[j].x)*(point[i].x-point[j].x) + (point[i].y-point[j].y)*(point[i].y-point[j].y)));
				if (distances >= 10.0 && distances <= 1000.0)
				{
					e[count].begin_id = point[i].id;
					e[count].end_id = point[j].id;
					e[count].weight = distances;
					count++;
				}
			}
		}

		sort(e, e+count, cmp);

		int m = 0;
		make_set();
		int x, y;
		double result = 0;

		while (m != count)
		{
			x = find_set(e[m].begin_id);
			y = find_set(e[m].end_id);

			if (x != y)
			{
				union_set(x, y);
				result += e[m].weight;
			}

			m++;
		}

		int count = 0;
		for (int i = 0; i < n; i++)
			if (point[i].id == father[point[i].id])
				count++;

		if (count == 1)
			printf("%.1lf\n", result*100);
		else
			cout << "oh!" << endl;
	}
	return 0;
}

抱歉!评论已关闭.