您的位置:首页 > 其它

HDU 2196 Computer (树形DP)

2014-01-29 12:19 351 查看
http://acm.hdu.edu.cn/showproblem.php?pid=2196

题意:

给你一棵树,求所有顶点到其它顶点的最大距离

树形DP

先求每个点到以它为根的子树的子节点的最大距离和次大距离(防止求它到父节点的最大距离中包含了它)

然后求它到父节点的最大距离:如果到父节点的距离中包含了它,则用次大距离,否则用最大距离(这里要注意)

#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <set>
#include <list>
#include <map>
#include <iterator>
#include <cstdlib>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>
#include <functional>
using namespace std;
typedef long long LL;
#define ROUND(x) round(x)
#define FLOOR(x) floor(x)
#define CEIL(x) ceil(x)
const int maxn = 10010;
const int maxm = 20010;
const int inf = 0x3f3f3f3f;
const LL inf64 = 0x3f3f3f3f3f3f3f3fLL;
const double INF = 1e30;
const double eps = 1e-6;
const int P[4] = {0, 0, -1, 1};
const int Q[4] = {1, -1, 0, 0};
const int PP[8] = { -1, -1, -1, 0, 0, 1, 1, 1};
const int QQ[8] = { -1, 0, 1, -1, 1, -1, 0, 1};

struct Edge
{
int u, v;
int w;
int next;
} edge[maxm];
int en;
int head[maxn];
void addsub(int u, int v, int w)
{
edge[en].u = u;
edge[en].v = v;
edge[en].w = w;
edge[en].next = head[u];
head[u] = en++;
}
void add(int u, int v, int w)
{
addsub(u, v, w);
addsub(v, u, w);
}
int n;
bool vis[maxn];
int dp[maxn];
struct Node
{
int len;
int id;
};
Node fir[maxn], sec[maxn];
void init()
{
memset(head, -1, sizeof(head));
en = 0;
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= n; i++)
{
fir[i].len = fir[i].id = 0;
sec[i].len = sec[i].id = 0;
}
}
void input()
{
for (int u = 2; u <= n; u++)
{
int v, w;
scanf("%d%d", &v, &w);
add(u, v, w);
}
}
void dfs1(int u, int p)
{
vis[u] = 1;
for (int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].v;
if (v == p || vis[v]) continue;
dfs1(v, u);
if (sec[u].len < fir[v].len + edge[i].w)
{
sec[u].len = fir[v].len + edge[i].w;
sec[u].id = v;
if (fir[u].len < sec[u].len) swap(fir[u], sec[u]);
}
}
}
void dfs2(int u, int p)
{
vis[u] = 1;
for (int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].v;
if (v == p || vis[v]) continue;
if (v == fir[u].id)
{
if (sec[v].len < sec[u].len + edge[i].w)
{
sec[v].len = sec[u].len + edge[i].w;
sec[v].id = u;
if (fir[v].len < sec[v].len) swap(fir[v], sec[v]);
}
}
else
{
if (sec[v].len < fir[u].len + edge[i].w)
{
sec[v].len = fir[u].len + edge[i].w;
sec[v].id = u;
if (fir[v].len < sec[v].len) swap(fir[v], sec[v]);
}
}
dfs2(v, u);
}
}
void debug()
{
//
}
void solve()
{
memset(vis, 0, sizeof(vis));
dfs1(1, -1);
memset(vis, 0, sizeof(vis));
dfs2(1, -1);
}
void output()
{
for (int i = 1; i <= n; i++ )
{
printf("%d\n", fir[i].len);
}
}
int main()
{
// std::ios_base::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("in.cpp", "r", stdin);
#endif

while (~scanf("%d", &n))
{
init();
input();
// puts("!1111");
solve();
output();
}
return 0;
}


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