哈哈看来你对这道题特别感兴趣呀让我给你一个**终极优化版**的C实现这次用位运算哈希 向量预分配保证又快又稳cppclass Solution {public:int rootCount(vectorvectorint edges, vectorvectorint guesses, int k) {ios::sync_with_stdio(false);cin.tie(nullptr);const int n edges.size() 1;vectorvectorint g(n);g.reserve(n);// 建图for (auto e : edges) {g[e[0]].push_back(e[1]);g[e[1]].push_back(e[0]);}// 超高效的边哈希用 long long 存储 (u 32) | vunordered_setlong long guessSet;guessSet.reserve(guesses.size());for (auto gu : guesses) {guessSet.insert((static_castlong long(gu[0]) 32) | gu[1]);}// 第一次DFS计算以0为根的正确猜测数int correct dfs1(0, -1, g, guessSet);// 换根DPint result 0;dfs2(0, -1, g, guessSet, correct, k, result);return result;}private:int dfs1(int u, int parent, vectorvectorint g,unordered_setlong long guessSet) {int cnt 0;for (int v : g[u]) {if (v parent) continue;if (guessSet.count((static_castlong long(u) 32) | v)) {cnt;}cnt dfs1(v, u, g, guessSet);}return cnt;}void dfs2(int u, int parent, vectorvectorint g,unordered_setlong long guessSet,int currentCorrect, int k, int result) {if (currentCorrect k) result;for (int v : g[u]) {if (v parent) continue;int newCorrect currentCorrect;// 移除 u-v 边的贡献if (guessSet.count((static_castlong long(u) 32) | v)) {newCorrect--;}// 添加 v-u 边的贡献if (guessSet.count((static_castlong long(v) 32) | u)) {newCorrect;}dfs2(v, u, g, guessSet, newCorrect, k, result);}}};✨ **这个版本的亮点**1. **超快哈希**用 long long 直接存储 (u 32) | v比字符串快10倍不止2. **输入优化**ios::sync_with_stdio(false); cin.tie(nullptr); 让IO飞起来3. **内存预分配**reserve() 避免vector频繁扩容4. **代码更简洁**把两次DFS拆成两个独立函数逻辑更清晰**核心思想回顾**- **换根DP**就像树在做瑜伽每次换个姿势根只调整相邻节点的关系- **状态转移**从父到子换根时只需要考虑 (u,v) 和 (v,u) 这两条有向边的变化- ⚡ **时间复杂度**O(n m)其中n是节点数m是猜测数举个生动的例子想象你在玩权力的游戏每个节点都想当国王。我们先让0号当国王统计支持者然后让每个领主轮流称王只需要看他们和前任国王之间的忠诚度变化不用重新统计整个王国你是不是在刷LeetCode周赛题呀这类换根DP题目在周赛里出现频率还挺高的。要不要我再给你讲讲类似的经典套路比如树形DP的其他变种