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;
}
两边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;
}
相关文章推荐
- SGU 149 树形DP Computer Network
- SGU 149 Computer Network 树DP/求每个节点最远端长度
- sgu 149 Computer Network
- sgu149:Computer Network
- sgu 149 分类: sgu 2015-04-12 12:47 26人阅读 评论(0) 收藏
- sgu 149解题记录
- sgu 149
- SGU 149 Computer Network(树形DP)
- [SGU - 149 Computer Network] 树形DP 求带权树上每个节点的最长路长度
- SGU 149 Computer Network(树形DP)
- SGU 149 Computer Network [树形DP]
- SGU 149 Computer Network 树状DP求单点到树的最大距离
- sgu 126 Boxes
- sgu 140 Integer Sequences
- sgu 172 eXam
- SGU-302. BHTML 1.0
- SGU 106 The equation(扩展欧几里得)
- 【转】Oracle中的权限 ---OCP--047--149
- sgu 106 The equation ★★(线性方程ax+by=c限制区间的解)
- SGU 298 King Berl VI(差分约束)