题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=2196
解题思路化无根树为有根树进行分析: 蓝色区域为以2为根的子树,红色区域为以2的父亲结点1为根的(子)树,不包含以2为根子树的部分。 我们定义: dp[i][0]表示节点i与以i为根的子树内最远的叶子节点之间的距离; dp[i][1]表示节点i与非子树内最远的叶子节点之间的距离。 disMAX[i]的含义与dp[i][0]一致; disMIN表示以i为根节点的子树内,节点i与次最远叶子节点之间的距离。
dp[i][0]比较好求,只要先dfs到底,在递归刷新每个节点的最大距离即可。 而求dp[i][1]则需要边dfs边刷新dp[i][1]。 假设节点u有n个子节点,分别是v1,v2…vn 那么 如果vi不是u最长距离经过的节点,dp[vi][1] = cost(vi,u)+max(disMAX[u], dp[u][1]); 如果vi是u最长距离经过的节点,那么不能选择f[u][0],因为这保存的就是最长距离,要选择以u为根子树的次最大距离,可得dp[vi][1] = cost(vi, u) + max(disMIN[u], dp[u][1]);
细节在代码中体现。
AC代码#include
#define pb push_back
#define ll long long
using namespace std;
const int N=1e5+100;
struct computer
{
int to,cost;//to表示与i相连的节点,cost表示二者的边权
};
int n,to,cost;
ll dp[N][2],disMAX[N],disMIN[N],pathMAX[N];//dp,disMAX,disMIN含义如上,pathMAX[i]=j表示以i为根节点的最长路径的儿子节点为j。
vector g[N];
void dfs1(int x,int fa)//求disMAX(即dp[][0]),和disMIN,以及保存路径
{
for(int i=0;idisMAX[x])//判断是否要刷新最大距离,刷新
{
disMIN[x]=disMAX[x];//把原最大距离给次最大距离
disMAX[x]=dis;//更新最大距离
dp[x][0]=disMAX[x];//disMAX与dp[][0]同步刷新
pathMAX[x]=g[x][i].to;//保存最大距离路径
}
else if(dis>disMIN[x]) disMIN[x]=dis;//不刷新最大距离,判断一下是否刷新次最大距离
}
}
void dfs2(int x,int fa){//求dp[][1]
for(int i=0;i>n)
{
//每次的初始化不可缺少
memset(dp,0,sizeof dp);
memset(disMAX,0,sizeof disMAX);
memset(disMIN,0,sizeof disMIN);
memset(pathMAX,0,sizeof pathMAX);
for(int i=1;ito>>cost;
tmp.to=to,tmp.cost=cost;
g[i].pb(tmp);
tmp.to=i;
g[to].pb(tmp);
}
dfs1(1,-1);
dfs2(1,-1);
for(int i=1;i
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?