您的位置:首页 > 其它

sgu 149 Computer Network 树形dp

2013-11-28 22:40 197 查看
     一棵带边权的树,对每个节点,求离这个节点最远的节点到它的距离...

       两边dps,第一遍记录一下每个节点的子树当中最深和次深的深度和该深度来源节点。第二遍从父节点取出一个最长的并且不通过当前节点的最长的深度去更新当前节点的最深次深这两个值和其来源节点,然后该节点记录的最大深度就是这个节点的答案了。

       #include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <memory.h>
#include <vector>
using namespace std;
typedef long long ll;
const int maxn=12000;
struct edge
{
int v,w;
edge(){}
edge(int x,int y)
{
v=x; w=y;
}
};

vector<edge> g[maxn];
int n,m;
int x,y;
int way[maxn][3];
int tg[maxn][3];
int ans[maxn];
void dfs(int u,int fa)
{
way[u][0]=way[u][1]=0;
tg[u][0]=tg[u][1]=u;
for (int j=0; j<g[u].size(); j++)
{
int v=g[u][j].v;
if (v==fa) continue;
dfs(v,u);
if (way[v][0]+g[u][j].w>way[u][0])
{
way[u][1]=way[u][0];
tg[u][1]=tg[u][0];
way[u][0]=way[v][0]+g[u][j].w;
tg[u][0]=v;
}
else
if (way[v][0]+g[u][j].w>way[u][1])
{
way[u][1]=way[v][0]+g[u][j].w;
tg[u][1]=v;
}
}
}

void dfs2(int u,int fa,int wei)
{

int tmp;
if (tg[fa][0]!=u) tmp=way[fa][0];
else tmp=way[fa][1];
int id;
if (tmp+wei>way[u][0])
{
way[u][1]=way[u][0];
tg[u][1]=tg[u][0];
way[u][0]=tmp+wei;
tg[u][0]=fa;
}
else if (tmp+wei>way[u][1])
{
way[u][1]=tmp+wei;
tg[u][1]=fa;
}

ans[u]=way[u][0];

for (int j=0; j<g[u].size(); j++)
{
int v=g[u][j].v;
if (v==fa) continue;
dfs2(v,u,g[u][j].w);
}
}
int main()
{
// freopen("in.txt","r",stdin);
memset(ans,0,sizeof ans);
memset(tg,0,sizeof tg);
memset(way,0,sizeof way);
scanf("%d",&n);
for (int i=2; i<=n; i++)
{
scanf("%d%d",&x,&y);
g[i].push_back(edge(x,y));
g[x].push_back(edge(i,y));
}
dfs(1,0);
dfs2(1,0,0);
for (int i=1; i<=n; i++)
printf("%d\n",ans[i]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: