1405 树的距离之和
生活随笔
收集整理的這篇文章主要介紹了
1405 树的距离之和
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1405 樹的距離之和
基準時間限制:1 秒 空間限制:131072 KB 給定一棵無根樹,假設它有n個節點,節點編號從1到n, 求任意兩點之間的距離(最短路徑)之和。 Input 第一行包含一個正整數n?(n?<=?100000),表示節點個數。 后面(n?-?1)行,每行兩個整數表示樹的邊。 Output 每行一個整數,第i(i?=?1,2,...n)行表示所有節點到第i個點的距離之和。 Input示例 4 1?2 3?2 4?2 Output示例 5 3 5 5思路:dfs
先選一個根節點,然后dfs求出所有點到這個點的距離最小值之和,過程中d[]記錄當前點下所有子節點到這個點的最小距離之和,node[]
記錄當前的點有多少個子節點,包括本身。然后這樣根節點的答案就有了,然后他的子節點可以根據根節點來更新的得到,d[n]+=d[m]-(d[n]+node[n])+node[m]-node[n];
然后dfs一遍就可以更新了。
1 #include<stdio.h> 2 #include<algorithm> 3 #include<iostream> 4 #include<string.h> 5 #include<stdlib.h> 6 #include<queue> 7 #include<set> 8 #include<vector> 9 #include<map> 10 using namespace std; 11 typedef long long LL; 12 vector<int>vec[100005]; 13 LL d[100005]; 14 LL node[100005]; 15 bool flag[1000005]; 16 void dfs(int n); 17 void slove(int n); 18 int main(void) 19 { 20 int n; 21 scanf("%d",&n); 22 int i,j; 23 for(i = 0; i < n-1; i++) 24 { 25 int x; 26 int y; 27 scanf("%d %d",&x,&y); 28 vec[x].push_back(y); 29 vec[y].push_back(x); 30 } 31 memset(flag,0,sizeof(flag)); 32 memset(d,0,sizeof(d)); 33 dfs(1); 34 memset(flag,0,sizeof(flag)); 35 slove(1); 36 for(i = 1; i <= n; i++) 37 printf("%lld\n",d[i]); 38 return 0; 39 } 40 void dfs(int n) 41 { 42 node[n]++; 43 flag[n] = true; 44 int i,j; 45 for(i = 0; i < vec[n].size(); i++) 46 { 47 int x = vec[n][i]; 48 if(!flag[x]) 49 { 50 dfs(x); 51 node[n]+=node[x]; 52 d[n]+=d[x]; 53 d[n]+=node[x]; 54 } 55 } 56 } 57 void slove(int n) 58 { 59 flag[n] = true; 60 int i; 61 for(i = 0; i < vec[n].size(); i++) 62 { 63 int x = vec[n][i]; 64 if(!flag[x]) 65 { 66 LL y = node[n]-node[x]; 67 d[x] += d[n] - (d[x] +node[x])+y; 68 node[x]+=y;//printf("%d %lld\n",x,d[x]); 69 //flag[x] = true; 70 slove(x); 71 } 72 } 73 }
?
轉載于:https://www.cnblogs.com/zzuli2sjy/p/5932118.html
總結
以上是生活随笔為你收集整理的1405 树的距离之和的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jQuery选择器的效率问题
- 下一篇: [na]华为acl(traffic-fi