30分求助(只有1 3 4AC)
查看原帖
30分求助(只有1 3 4AC)
1037544
mazel楼主2024/3/14 23:41

30分求助
使用建立哈夫曼树的方式
这样可能会超时,但不明白为什么会WA

//用构建哈夫曼树的方式
class point {
public:
	int signal = 0;         ///用来判断是否遍历过,默认值为0,若为0,则没有遍历
	int weight;       //用来代表果子数目
};
int N;       //果子种类数
int d;     //总的体力耗费值

//选取未合并果子堆中重量最小的两堆
void Select(point* p, int& min1, int& min2,int q)
{
	//q+1代表目前已有堆数
	//min1 min2分别代表重量最小两个堆的位置
	int MIN1 = 30000;
	int MIN2 = 30000;
	for (int i = 0; i <= q; i++)
	{
		if (p[i].weight < MIN1 && p[i].signal == 0)   //若出现比已知最小堆还小的堆,且该堆未被遍历
		{
			MIN1 = p[i].weight;
			min1 = i;
		}
	}

	//寻找第二小的堆
	for (int i = 0; i <= q; i++)
	{
		//第二小堆不能与第一小堆重复
		if (p[i].weight < MIN2 && p[i].signal == 0 && i != min1)
		{
			MIN2 = p[i].weight;
			min2 = i;
		}
	}
}
int main()
{
	cin >> N;
	point* p = new point[2*N];
	int a = 0;
	for (int i = 0; i < N; i++)
	{
		cin >> a;
		p[i].weight = a;
	}
	//总过经过N-1此合并可以完成,可以看作生成N-1个节点构建哈夫曼树的过程
	for (int i = N; i <= 2 * N - 2; i++)
	{
		//优先选取未合并果子堆中重量最小的两队,即哈夫曼树中权值最小的两个节点
		//每次合并都会生成一个新堆,可以看作两个子节点生成一个父节点
		int min1 = -1;
		int min2 = -1;
		Select(p, min1, min2, i - 1);
		//代表这两个堆已经被合并了
		p[min1].signal = 1;
		p[min2].signal = 1;
		//生成新堆
		p[i].weight = p[min1].weight + p[min2].weight;
		//增加总体力耗费量,为两堆的质量之和
		d += p[i].weight;
	}
	cout << d;
	return 0;
}
2024/3/14 23:41
加载中...