leetcode 834. 树中距离之和

    科技2023-10-31  106

    leetcode 834. 树中距离之和

    题目详情

    题目链接 给定一个无向、连通的树。树中有 N 个标记为 0…N-1 的节点以及 N-1 条边 。 第 i 条边连接节点 edges[i][0] 和 edges[i][1] 。 返回一个表示节点 i 与其他所有节点距离之和的列表 ans。

    示例 1: 输入: N = 6, edges = [[0,1],[0,2],[2,3],[2,4],[2,5]] 输出: [8,12,6,10,10,10] 解释: 如下为给定的树的示意图: 0 / \ 1 2 /|\ 3 4 5 我们可以计算出 dist(0,1) + dist(0,2) + dist(0,3) + dist(0,4) + dist(0,5) 也就是 1 + 1 + 2 + 2 + 2 = 8。 因此,answer[0] = 8,以此类推。

    说明: 1 <= N <= 10000

    我的代码

    class Solution { public: vector<int> sumOfDistancesInTree(int N, vector<vector<int>>& edges) { if (N == 1) { return {0}; } if (N == 2) { return {1, 1}; } vector<vector<int>> dist(N, vector<int> (N, N)); for (auto & edge : edges) { dist[edge[0]][edge[1]] = 1; dist[edge[1]][edge[0]] = 1; } for (int i = 0; i < N; ++i) { dist[i][i] = 0; } for (int m = 0; m < N; ++m) { for (int i = 0; i < N; ++i) { for (int j = 0; j < N; ++j) { dist[i][j] = min(dist[i][j], dist[i][m] + dist[m][j]); dist[j][i] = dist[i][j]; } } } vector<int> result(N, 0); for (int i = 0; i < N; ++i) { for (int j = 0; j < N; ++j) { result[i] += dist[i][j]; } } return result; } };

    我的成绩

    执行结果:超出时间限制 64 / 69 个通过测试用例

    一些想法

    我使用的弗洛伊德算法,但是过不去。。。

    执行用时为 84 ms 的范例

    class Solution { public: int num[10010],cost[10010]; vector<int> res; int e[10010],ne[20010],to[20010],idx; void dfs(int n,int f) { for(int i=e[n];i;i=ne[i]) { if(to[i]==f) continue; dfs(to[i],n); num[n]+=num[to[i]]; cost[n]+=cost[to[i]]+num[to[i]]; } num[n]++; } void dfs1(int n,int f,int c) { res[n]=c; for(int i=e[n];i;i=ne[i]) { if(to[i]==f) continue; dfs1(to[i],n,c+num[0]-num[to[i]]-num[to[i]]); } } vector<int> sumOfDistancesInTree(int N, vector<vector<int>>& edges) { res.resize(N); for(auto &c:edges) { to[++idx]=c[1]; ne[idx]=e[c[0]]; e[c[0]]=idx; to[++idx]=c[0]; ne[idx]=e[c[1]]; e[c[1]]=idx; } dfs(0,-1); dfs1(0,-1,cost[0]); return res; } };

    思考

    参见官方解答

    Processed: 0.019, SQL: 9