#include #include #include using namespace std; /* Huffman 树节点 在竞赛中一般不需要真的建树,只关心权值 */ struct Node { long long w; // 当前节点权值 Node(long long _w) : w(_w) {} }; /* priority_queue 默认是大根堆 这里通过重载比较函数,使其变为小根堆 */ struct cmp { bool operator()(const Node& a, const Node& b) const { return a.w > b.w; // 权值小的优先 } }; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; /* 优先队列(小根堆) 每次可以 O(log n) 取出最小的两个权值 */ priority_queue, cmp> pq; // 读入 n 个权值 for (int i = 0; i < n; i++) { long long x; cin >> x; pq.push(Node(x)); } /* 特判:只有一个节点 WPL = 0(没有边) */ if (n == 1) { cout << 0 << '\n'; return 0; } long long WPL = 0; /* Huffman 树构造过程 每次取最小的两个合并 */ while (pq.size() > 1) { Node a = pq.top(); pq.pop(); Node b = pq.top(); pq.pop(); long long mergedWeight = a.w + b.w; WPL += mergedWeight; pq.push(Node(mergedWeight)); } // 输出带权路径长度 cout << WPL << '\n'; return 0; }