首页 > 代码库 > 51Nod 1405 树的距离之和 (dfs)

51Nod 1405 树的距离之和 (dfs)

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1405

中文题面不解释了,两次dfs,第一次自下向上,第二次自上向下。

ans[i]表示i节点的答案,cnt[i]表示i节点为root的子树的节点个数,d[i]表示i节点为root的子树的答案。

 1 //#pragma comment(linker, "/STACK:102400000, 102400000") 2 #include <algorithm> 3 #include <iostream> 4 #include <cstdlib> 5 #include <cstring> 6 #include <cstdio> 7 #include <vector> 8 #include <cmath> 9 #include <ctime>10 #include <list>11 #include <set>12 #include <map>13 using namespace std;14 typedef long long LL;15 typedef pair <int, int> P;16 const int N = 1e5 + 5;17 LL cnt[N], d[N], ans[N], n;18 vector <int> edge[N];19 20 void dfs1(int u, int p) {21     cnt[u] = 1;22     d[u] = 0;23     for(int i = 0; i < edge[u].size(); ++i) {24         int v = edge[u][i];25         if(v == p)26             continue;27         dfs1(v, u);28         cnt[u] += cnt[v];29         d[u] += cnt[v] + d[v];30     }31 }32 33 void dfs2(int u, int p) {34     if(p != -1) {35         ans[u] = (ans[p] - d[u] - cnt[u]) + (n - cnt[u]) + d[u];36     } else {37         ans[u] = d[u];38     }39     for(int i = 0; i < edge[u].size(); ++i) {40         int v = edge[u][i];41         if(v == p)42             continue;43         dfs2(v, u);44     }45 }46 47 int main()48 {49     int u, v;50     while(~scanf("%lld", &n)) {51         for(int i = 1; i <= n; ++i) {52             edge[i].clear();53         }54         for(int i = 1; i < n; ++i) {55             scanf("%d %d", &u, &v);56             edge[u].push_back(v);57             edge[v].push_back(u);58         }59         dfs1(1, -1);60         dfs2(1, -1);61         for(int i = 1; i <= n; ++i) {62             printf("%lld\n", ans[i]);63         }64     }65     return 0;66 }

 

51Nod 1405 树的距离之和 (dfs)