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