您的位置:首页 > 其它

SGU 149 树形DP Computer Network

2015-07-31 10:43 281 查看
  这道题搜了一晚上的题解,外加自己想了半个早上,终于想得很透彻了。于是打算好好写一写这题题解,而且这种做法比网上大多数题解要简单而且代码也比较简洁。

  首先要把题读懂,把输入读懂,这实际上是一颗有向树。第i(2≤i≤n)行的两个数u,d,其中u是i的父亲结点,d是距离。

  第一遍DFS我们可以计算出以u为根的子树中,距离u最远的结点的距离d(u, 0)以及次远的距离d(u, 1)。而且,这两个不在u的同一棵子树中,如果u只有一个孩子,那么d(u, 1) = 0

  第一遍DFS完以后,因为1是整棵树的跟,所以d(1, 0)就是距离1最远的距离。然后第二遍DFS,这次是用根的信息来更新它的子节点,此时d(u,0)d(u,1)的含义变为整棵树中距u最长和次长的距离。

  如图:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;

const int maxn = 10000 + 10;
vector<int> G[maxn], C[maxn];
int n;

int d[maxn][2];

void dfs(int u)
{
for(int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
dfs(v);
int t = d[v][0] + C[u][i];
if(t > d[u][0]) swap(t, d[u][0]);
if(t > d[u][1]) swap(t, d[u][1]);
}
}

void dfs2(int u)
{
for(int i = 0; i < G[u].size(); i++)
{
int v = G[u][i], t, w = C[u][i];
if(d[v][0] + w == d[u][0]) t = w + d[u][1];
else t = w + d[u][0];
if(t > d[v][0]) swap(t, d[v][0]);
if(t > d[v][1]) swap(t, d[v][1]);
dfs2(v);
}
}

int main()
{
scanf("%d", &n);
for(int u = 2; u <= n; u++)
{
int v, d; scanf("%d%d", &v, &d);
G[v].push_back(u); C[v].push_back(d);
}

dfs(1);
dfs2(1);

for(int i = 1; i <= n; i++) printf("%d\n", d[i][0]);

return 0;
}


代码君
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: