//老师教的一种思路,但楼主写出来后并没有完全通过PTA一道题上的测试,也许是哪里的问题楼主没注意到,暂且记录
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//#include<stdafx.h>
#include<iostream>
#include<cstring>
using namespace std;
typedef int Elemtype;
typedef struct hajishu* manbo;
int maxd = 1000;
struct hajishu
{
int name=0;//该节点的名称
Elemtype data=-1;//当前节点的数据
int left = 0, right = 0;//该节点的左右子树的名称,为0代表没有
int parent = 0;//该节点的父母辈的名称
};
int main()
{
hajishu H[maxd];
int count = 0, i = 1;
cin >> count;
while (i <= count)//从1开始保存几位树
{
cin>>H[i].data;
H[i].name = i;
i++;
}
/*
i=1;
while (i <= count)//
{
printf("name%d data%d zuo%d you%d fumu%d\n", H[i].name, H[i].data, H[i].left, H[i].right, H[i].parent);
i++;
}
*/
//两个指针找当前没有父母的结点最小值
manbo top1 = &H[1];
manbo top2 = &H[2];
//printf("hajimi");
int ii = 0;
//int a = 0;//这个本来是防止死循环的,测试时循环条件是a<20
while (1)
{
//a++;
ii = 1;
//找两个结点权重最小的而且不能有父母
while (ii <= count)//从头到尾
{
if (top1->data > H[ii].data && H[ii].name != top2->name && H[ii].parent == 0)
{
top1 = &H[ii];
}
ii++;
}
ii = 1;
while (ii <= count)
{
if (top2->data > H[ii].data && top1->name != H[ii].name && H[ii].parent == 0)
{
top2 = &H[ii];
}
ii++;
}
//找两个结点权重最小的
//新建结点,这两个最小的有父母的,父母的权重是他们的权重合
H[ii].data = top1->data + top2->data;
H[ii].name = ii;
top1->parent = ii;
top2->parent = ii;
H[ii].left = top1->name;
H[ii].right = top2->name;
count++;//树的最大值修改
ii = 1;
while (H[ii].parent != 0 && ii <= count)
{//修改两个指针的初始位置,跳过有父母的结点,找第一个没有父母的结点
//因为最后可能指针指向的是最末尾的,第二次循环就可能找不到
ii++;
}
if (ii > count)
{
break;
}
top1 = &H[ii];//修改成功
ii++;//top2的寻找要从下一位开始
while (H[ii].parent != 0 && ii <= count)
{
ii++;
}
if (ii > count)//如果找出去了都找不到,那么此时只剩一个节点了,他一定是最上面的结点
{
break;
}
top2 = &H[ii];
}
i = 1;
int sum = 0;
while (i<=(count+1)/2)//计算这个树的WPL,只需要管叶结点即可,i<=叶节点数
{//所有生成的新结点数=原结点*2-1
top1 = &H[i];
int num=0;//num代表楼层
while (top1->parent!= 0)
{
top1 = &H[top1->parent];
num++;
}
sum += H[i].data * num;//当前节点权重*楼层数
i++;//下一节点
}
printf("%d\n", sum);
return 0;
}
190

被折叠的 条评论
为什么被折叠?



