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

  • 联系
  • 订阅
  • 管理

View Post

HDU 3道最小生成树题目

//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;
}

posted on 2010-12-06 21:38  sysuwhj  阅读(2916)  评论(0)    收藏  举报

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