4080:Huffman编码树
-
- 总时间限制:
- 1000ms 内存限制:
- 65536kB
-
-
描述
-
构造一个具有n个外部节点的扩充二叉树,每个外部节点Ki有一个Wi对应,作为该外部节点的权。使得这个扩充二叉树的叶节点带权外部路径长度总和最小:
Min( W1 * L1 + W2 * L2 + W3 * L3 + … + Wn * Ln)
Wi:每个节点的权值。
Li:根节点到第i个外部叶子节点的距离。
编程计算最小外部路径长度总和。
-
输入
-
第一行输入一个整数n,外部节点的个数。第二行输入n个整数,代表各个外部节点的权值。
2<=N<=100 -
输出
-
输出最小外部路径长度总和。
-
样例输入
-
41 1 3 5 -
样例输出
-
17
-
-
\
#include<iostream> #include<vector> #include<string> #include<map> #include<queue> #define INT_MAX 2000000000 using namespace std; struct node { int flag=0; int w; int parent; int leftchild, rightchild; }; int main() { int n; cin >> n; vector<node> tree(2 * n - 1); for (int i = 0; i < n; i++) { int tw; cin >> tw; node temp; temp.flag = 1; temp.leftchild = -1; temp.parent = -1; temp.rightchild = -1; temp.w = tw; tree[i] = temp; } for (int i = n; i < 2 * n - 1; i++) { node temp; temp.parent = temp.leftchild = temp.rightchild = -1; tree[i] = temp; } for (int i = n; i < 2 * n - 1; i++) { int minw1 = INT_MAX - 1; int minw2 = INT_MAX; int minl = -1; int minr = -1; for (int j = 0; j < i; j++) { if (tree[j].parent==-1&&tree[j].w < minw1) { minw2 = minw1; minr = minl; minw1 = tree[j].w; minl = j; } else if (tree[j].parent == -1 && tree[j].w < minw2) { minw2 = tree[j].w; minr = j; } } tree[i].w = tree[minl].w + tree[minr].w; tree[i].leftchild = minl; tree[i].rightchild = minr; tree[minl].parent = i; tree[minr].parent = i; } int sum = 0; int layer = 1; queue<node> q; q.push(tree[2 * n - 2]); while (q.size() != 0) { queue<node> tq; while (q.size() != 0) { node cur = q.front(); q.pop(); int lnode = cur.leftchild; int rnode = cur.rightchild; if (lnode != -1) { node t = tree[lnode]; tq.push(t); if (t.flag == 1) { sum += t.w*layer; } } if (rnode != -1) { node t = tree[rnode]; tq.push(t); if (t.flag == 1) { sum += t.w*layer; } } } q = tq; layer++; } cout << sum << endl; system("pause"); }
\
\
\