51nod 1405 树的距离和
2017-07-28 20:32
393 查看
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1405
题意:
有n个节点的无根树,求每个节点分别到其他n-1个节点的距离之和。
思路:
设dp[x]表示节点x到其他n-1个节点的距离和。
一个dp[x]是很好求的,把x当成根,一遍dfs,把所有点的深度加起来,就可以求出dp[x]。
得知dp[x]如何求得dp[y]呢?此时x是父节点,y是儿子节点。我们再增加一个儿子节点z,这三个点的联系为y–x–z。知道dp[x],求dp[y],那么,等于dp[y] = dp[x]-son[y]+(n-son[y]),dp[x]即减去y子节点的个数,再加上非y子节点得到个数。
代码:
题意:
有n个节点的无根树,求每个节点分别到其他n-1个节点的距离之和。
思路:
设dp[x]表示节点x到其他n-1个节点的距离和。
一个dp[x]是很好求的,把x当成根,一遍dfs,把所有点的深度加起来,就可以求出dp[x]。
得知dp[x]如何求得dp[y]呢?此时x是父节点,y是儿子节点。我们再增加一个儿子节点z,这三个点的联系为y–x–z。知道dp[x],求dp[y],那么,等于dp[y] = dp[x]-son[y]+(n-son[y]),dp[x]即减去y子节点的个数,再加上非y子节点得到个数。
代码:
#include <iostream> #include <cstring> #include <vector> #include <cstdio> using namespace std; const int maxn = 1e5+5; vector<int> edges[maxn]; int n, a, b; bool vis[maxn]; int son[maxn]; long long dp[maxn]; void dfs1(int rt, int depth){ int len = edges[rt].size(); vis[rt] = true; son[rt] = 1; dp[1] += depth; for(int i=0; i<len; ++i){ int sn = edges[rt][i]; if(!vis[sn]){ dfs1(sn, depth+1); son[rt] += son[sn]; } } } void dfs2(int rt){ vis[rt] = true; int len = edges[rt].size(); for(int i=0; i<len; ++i){ int sn = edges[rt][i]; if(!vis[sn]){ dp[sn] = dp[rt]+n-son[sn]*2; dfs2(sn); } } } int main(){ scanf("%d", &n); for(int i=0; i<n-1; ++i) { scanf("%d%d", &a, &b); edges[a].push_back(b); edges[b].push_back(a); } dfs1(1, 0); memset(vis, 0, sizeof(vis)); dfs2(1); for(int i=1; i<=n; ++i){ printf("%lld\n", dp[i]); } return 0; }
相关文章推荐
- 51nod 1405 树的距离之和 (树形dp)
- 51nod 1405 树的距离之和
- 51nod 1405 树的距离之和【树型dp】
- 51nod 1405 树的距离之和 树形dp
- 51nod 1405 树的距离之和(树型dp)
- 51nod 1405 树的距离之和
- 51NOD-1405 树的距离之和(树形DP)
- 51nod-1405 树的距离之和
- 51nod 1405 树的距离之和
- 51nod 1405 树的距离之和
- 51nod 1405 树的距离之和【树形dp】
- 51nod 1405 树的距离之和 【dfs--记忆dp??树形dp??】
- 51Nod 1405 树的距离之和(dp)
- 51Nod-1405-树的距离之和
- 51Nod 1405 树的距离之和(dp)
- 51nod 1405 树的距离之和(DFS)
- 51nod 1405 树的距离之和 搜索+DP
- 51nod 1405 树的距离之和(dfs)
- 51nod 1405 树的距离之和 (两次dfs,树形dp)
- 51nod 1405 树的距离之和(DP)