51nod 1405 树的距离之和 搜索+DP
2017-11-27 19:04
417 查看
给定一棵无根树,假设它有n个节点,节点编号从1到n, 求任意两点之间的距离(最短路径)之和。
Input
Output
Input示例
Output示例
假设以第一个点为根节点,我们开始搜索,记录以当前节点的深度以及当前节点的子节点个数。
之后对于统计。
对于X节点,我们已经知道他的距离之和为dp【X】了。
那么他的子节点Y节点。
dp【Y】=dp[X] - num[y] + n - num[y]
解释一下:其他点到达y,有两种情况。第一种点在y节点的子树上。 也就是num【y】个,这num【y】个点
到达y要比到达x小1. 所以dp【x】-num【y】. 第二种情况,不在y的子树上的点,也就是n-num【y】个,
他们要比到达x多1.所以在原来的基础上再加上n - num[y]。
那么我们dfs来求dp即可。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<iostream>
using namespace std;
vector<long long>p[100010];
bool f[100010];//是否访问过
long long dp[100010];//当前深度到S的深度
long long num[100010];//子节点数量
long long n;
void dfs(long long s,long long depth)
{
long long len=p[s].size();
f[s]=1;
num[s]=1;
dp[1]+=depth;
for(long long i=0;i<len;i++)
{
if(!f[p[s][i]])
{
dfs(p[s][i],depth+1);
num[s]+=num[p[s][i]];
}
}
}
void solve(long long s)
{
long long len=p[s].size();
f[s]=1;
for(long long i=0;i<len;i++)
{
if(!f[p[s][i]])
{
dp[p[s][i]]=dp[s]+n-num[p[s][i]]*2;
solve(p[s][i]);
}
}
}
int main()
{
cin>>n;
for(long long i=2;i<=n;i++)
{
long long a,b;
cin>>a>>b;
p[a].push_back(b);
p[b].push_back(a);
}
dfs(1,0);
memset(f,0,sizeof(f));
solve(1);
for(long long i=1;i<=n;i++)
cout<<dp[i]<<endl;
}
Input
第一行包含一个正整数n (n <= 100000),表示节点个数。 后面(n - 1)行,每行两个整数表示树的边。
Output
每行一个整数,第i(i = 1,2,...n)行表示所有节点到第i个点的距离之和。
Input示例
4 1 2 3 2 4 2
Output示例
5 3 55
假设以第一个点为根节点,我们开始搜索,记录以当前节点的深度以及当前节点的子节点个数。
之后对于统计。
对于X节点,我们已经知道他的距离之和为dp【X】了。
那么他的子节点Y节点。
dp【Y】=dp[X] - num[y] + n - num[y]
解释一下:其他点到达y,有两种情况。第一种点在y节点的子树上。 也就是num【y】个,这num【y】个点
到达y要比到达x小1. 所以dp【x】-num【y】. 第二种情况,不在y的子树上的点,也就是n-num【y】个,
他们要比到达x多1.所以在原来的基础上再加上n - num[y]。
那么我们dfs来求dp即可。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<iostream>
using namespace std;
vector<long long>p[100010];
bool f[100010];//是否访问过
long long dp[100010];//当前深度到S的深度
long long num[100010];//子节点数量
long long n;
void dfs(long long s,long long depth)
{
long long len=p[s].size();
f[s]=1;
num[s]=1;
dp[1]+=depth;
for(long long i=0;i<len;i++)
{
if(!f[p[s][i]])
{
dfs(p[s][i],depth+1);
num[s]+=num[p[s][i]];
}
}
}
void solve(long long s)
{
long long len=p[s].size();
f[s]=1;
for(long long i=0;i<len;i++)
{
if(!f[p[s][i]])
{
dp[p[s][i]]=dp[s]+n-num[p[s][i]]*2;
solve(p[s][i]);
}
}
}
int main()
{
cin>>n;
for(long long i=2;i<=n;i++)
{
long long a,b;
cin>>a>>b;
p[a].push_back(b);
p[b].push_back(a);
}
dfs(1,0);
memset(f,0,sizeof(f));
solve(1);
for(long long i=1;i<=n;i++)
cout<<dp[i]<<endl;
}
相关文章推荐
- 51Nod 1405 树的距离之和(dp)
- 51nod 1405 树的距离和
- 51nod 1405 树的距离之和
- 51Nod-1405-树的距离之和
- 51nod 1405 树的距离之和(dfs)
- 51nod 1405 树的距离之和(DFS)
- 51nod 1405 树的距离之和(DP)
- 51Nod 1405 树的距离之和(dp)
- 51Nod 1405 树的距离之和 (树dp)
- 51nod 1405 树的距离之和 (两次dfs,树形dp)
- 51nod 1405 树的距离之和
- 51nod 1405 树的距离之和
- 51Nod 1405 树的距离之和(树形dp)
- 51nod 1405 树的距离之和 (两次dfs,树形dp)
- 51nod 1405 树的距离之和
- 51nod 1405 树的距离之和 (树形dp)
- 51nod 1405 树的距离之和【树型dp】
- 51nod 1405 树的距离之和
- 51nod 1405 树的距离之和 树形dp
- 51nod-1405 树的距离之和