POJ 3253 Fence Repair(优先队列)

本文通过实例讲解了如何使用优先队列优化哈夫曼树的构建过程,对比了两种不同算法的时间复杂度,并提供了完整的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

《C++标准程序库》上关于优先队列的介绍:

#include <iostream>
#include <queue>
using namespace std;

int main(void)
{
	priority_queue<double> q;

	q.push(66.6);
	q.push(22.2);
	q.push(44.4);

	cout << q.top() << ' ';
	q.pop();
	cout << q.top() << endl;
	q.pop();

	q.push(11.1);
	q.push(55.5);
	q.push(33.3);

	q.pop();

	while (!q.empty()) {
		cout << q.top() << ' ';
		q.pop();
	}
	cout << endl;

	return 0;
}

例:

http://poj.org/problem?id=3253

1、O(n^2):for+Select()

超时

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

struct Node {
	long long weight;
	unsigned int parent;
	unsigned int lchild;
	unsigned int rchild;
};

Node HT[40005] = {0};

long long Sum(const int &n)
{
	long long sum = 0;
	for (int i = n + 1; i <= 2 * n - 1; i++) {
		sum += HT[i].weight;
	}
	return sum;
}

void Select(const int &len, int &a, int &b)
{
	// 在HT[1..len]中选择parent为0且weight最小的两个结点,
	// 其序号分别为a和b。
	for (int i = 1; i <= len; i++) {
		if (HT[i].parent == 0) {
			a = i;
			break;
		}
	}
	for (int i = a + 1; i <= len; i++) {
		if (HT[i].parent == 0) {
			b = i;
			break;
		}
	}
	if (HT[a].weight > HT[b].weight)	//	保持a的始终小于b的,有序
		swap(a, b);
	for (int i = max(a, b) + 1; i <= len; i++) {
		if (HT[i].parent == 0) {
			if (HT[i].weight > HT[b].weight)
				continue;
			else if (HT[i].weight < HT[a].weight) {
				b = a;
				a = i;
			}
			else
				b = i;
		}
	}
	if ( !(HT[a].parent == 0 && HT[b].parent == 0) ) {
		cerr << "Error!" << endl;
		exit(1);
	}
}

void CreatHuffmanTree(const int &n)
{
	// weight存放n个字符的权值(均>0),构造哈夫曼树HT,
	// 并求出n个字符的哈夫曼编码HC
	for (int i = 1; i <= n; i++)
		cin >> HT[i].weight;
	for (int i = n + 1; i <= 2 * n - 1; i++) {
		// 在HT[1..i-1]中选择parent为0且weight最小的两个结点,
		// 其序号分别为s1和s2。
		int s1 = 0;
		int s2 = 0;
		Select(i - 1, s1, s2);
		HT[s1].parent = i;
		HT[s2].parent = i;
		HT[i].lchild = s1;
		HT[i].rchild = s2;
		HT[i].weight = HT[s1].weight + HT[s2].weight;
	}
}

int main(void)
{
//	freopen("cin.txt", "r", stdin);
	int n;
	cin >> n;
	if (n <= 1)
		cout << 0 << endl;
	else {		
		CreatHuffmanTree(n);
		cout << Sum(n) << endl;
	}

	return 0;
}

2、选k个最小值的算法用优先队列

参考:

#include <iostream>
#include <queue>
using namespace std;

typedef long long ll;	//	便于移植

int main(void)
{
	priority_queue< ll, vector<ll>, greater<ll> > q;
	int N;

	cin >> N;
	for (int i = 0; i < N; i++) {
		ll x;
		cin >> x;
		q.push(x);
	}

	ll cost = 0;
	for (;;) {
		ll a = q.top();
		q.pop();
		if (q.empty())
			break;
		ll b = q.top();
		q.pop();
		cost += a + b;
		q.push(a + b);
	}
	cout << cost << endl;

	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值