1 solutions
-
0
Guest MOD
-
0
#include <bits/stdc++.h> using namespace std; typedef long long ll; // 防止损伤值总和溢出,使用长整型 const int MAXN = 1e6 + 5; // 最大节点数,适配n≤1e6的测试点 vector<pair<int, int>> adj[MAXN]; // 无向邻接表:存储(相邻节点, 脆弱值) ll ans = 0; // 所有通信管道的总损伤值 int n; // 树的总节点数(用户数量) // 迭代DFS函数:计算子树大小并累加损伤值(避免递归栈溢出) void iterative_dfs() { // 栈元素:(当前节点u, 父节点parent, 是否已处理子节点) stack<tuple<int, int, bool>> stk; stk.emplace(1, -1, false); // 根节点1,父节点-1(无父节点),初始未处理 int sub_size[MAXN] = {0}; // 记录每个节点为根的子树大小 while (!stk.empty()) { // 手动拆解栈顶的三元组(兼容C++14,替代结构化绑定) tuple<int, int, bool> top = stk.top(); stk.pop(); int u = get<0>(top); // 当前节点 int parent = get<1>(top); // 当前节点的父节点 bool is_processed = get<2>(top); // 是否已处理子节点 if (!is_processed) { // 第一步:标记为“待处理”后重新入栈,后续处理子节点 stk.emplace(u, parent, true); // 逆序遍历邻接边(保证子节点处理顺序与递归一致) for (auto it = adj[u].rbegin(); it != adj[u].rend(); ++it) { int v = it->first; // 邻接节点v if (v != parent) { // 跳过父节点,只处理子节点 stk.emplace(v, u, false); } } } else { // 第二步:所有子节点已处理,计算当前节点的子树大小和损伤值 sub_size[u] = 1; // 子树大小初始为1(当前节点自身) for (auto &edge : adj[u]) { int v = edge.first; // 子节点v int c = edge.second; // 边u-v的脆弱值 if (v != parent) { // v是子节点(非父节点) sub_size[u] += sub_size[v]; // 累加子树大小 // 计算边的损伤值:|n - 2*子树大小| × 脆弱值 ans += (ll)abs(n - 2 * sub_size[v]) * c; } } } } } int main() { // 输入优化:关闭cin与stdio同步,加速输入 ios::sync_with_stdio(false); cin.tie(nullptr); cin >> n; // 读取节点总数 // 读取n-1条边,构建无向邻接表 for (int i = 0; i < n - 1; ++i) { int a, b, c; cin >> a >> b >> c; adj[a].emplace_back(b, c); adj[b].emplace_back(a, c); } iterative_dfs(); // 计算子树大小并累加损伤值 cout << ans << endl; // 输出总损伤值 return 0; }
Information
- ID
- 1602
- Time
- 2000ms
- Memory
- 256MiB
- Difficulty
- 7
- Tags
- (None)
- # Submissions
- 61
- Accepted
- 12
- Uploaded By