您的位置:首页 > 其它

hdu 4679 Terrorist’s destroy 树形DP

2013-08-15 20:51 375 查看
http://acm.hdu.edu.cn/showproblem.php?pid=4679

f[u],g[u],k[u]:分别代表u延伸出去的最长边长,第二长边长,第三长边长;

ff[u]:f[u]对应的子节点

gg[u]:g[u]对应的子节点

h[u]:沿着u的父节点方向的最长边

dp[u][0]:以u的所有子节点为根的子树中的子树的直径最大值

dp[u][1]:以u的所有子节点为根的子树中的子树的直径次大值

flag[u]:dp[u][0]对应的u的子节点

ddp[u]:除以u为根的子树外的子树的直径

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 100100;
int f[maxn] , g[maxn] , gg[maxn] , ff[maxn] , k[maxn] , h[maxn] , p[maxn];
struct Edge {
int v , w , next ,id;
Edge () {}
Edge (int v,int w,int next) : v(v) , w(w) , next(next) {};
}edge[maxn<<1];
int E, head[maxn] , n;
void init() {
E = 0; memset(head,-1,sizeof(int)*(n+1));
}
void addedge(int u,int v,int w) {
edge[E] = Edge(v ,w, head[u]); head[u] = E++;
edge[E] = Edge(u , w, head[v]); head[v] = E++;
}
queue <int> q;
bool vis[maxn];
int sta[maxn] , top;
void bfs() {
while(!q.empty()) q.pop();
for(int i=1;i<=n;i++) vis[i] = false;
q.push(1);
p[1] = -1;
top = 0;
sta[++top] = 1;
int u;
vis[1] = true;
while(!q.empty()) {
u = q.front(); q.pop();
for(int i=head[u];i!=-1;i=edge[i].next) {
int v = edge[i].v;
if(!vis[v]) {
p[v] = u;
q.push(v);
vis[v] = true;
sta[++top] = v;
}
}
}
}
void after_bfs() {
//printf("top number is %d\n" , top);
while(top > 0) {
int u = sta[top--];
vis[u] = false;
f[u] = g[u] = gg[u] = 0;
ff[u] = -1;
for(int i=head[u];i!=-1;i=edge[i].next) {
int v = edge[i].v;
if(v == p[u]) continue;
if(f[v] + 1 > f[u]) {
f[u] = f[v] + 1;
ff[u] = v;
}
}
for(int i=head[u];i!=-1;i=edge[i].next) {
int v = edge[i].v;
if(v == p[u]) continue;
if(v == ff[u]) continue;
if(f[v] + 1 > g[u]) {
g[u] = f[v] + 1;
gg[u] = v;
}
}
for(int i=head[u];i!=-1;i=edge[i].next) {
int v = edge[i].v;
if(v == p[u]) continue;
if(v == ff[u]) continue;
if(v == gg[u]) continue;
if(f[v] + 1 > k[u]) {
k[u] = f[v] + 1;
}
}
}
}
void after_bfs2() {
h[1] = 0;
for(int uu=2;uu<=n;uu++) {
int u = sta[uu];
int pa = p[u];
if(ff[pa] == u) {
h[u] = max(h[pa]+1 , g[pa]+1);
}
else {
h[u] = max(h[pa]+1 , f[pa]+1);
}
}
}
int dp[maxn][2] , flag[maxn];
void after_bfs3() {
int top = n;
int u;
for(int i=1;i<=n;i++) flag[i] = -1 , dp[i][0] = dp[i][1] = 0;
while(top > 0) {
u = sta[top--];
for(int i=head[u];i!=-1;i=edge[i].next) {
int v = edge[i].v;
if(v == p[u]) continue;
int tmp = max(f[v]+g[v],dp[v][0]);
if(tmp > dp[u][0]) {
dp[u][0] = tmp;
flag[u] = v;
}
}
for(int i=head[u];i!=-1;i=edge[i].next) {
int v = edge[i].v;
if(v == p[u] || v == flag[u]) continue;
int tmp = max(f[v]+g[v],dp[v][0]);
if(tmp > dp[u][1]) {
dp[u][1] = tmp;
}
}
}
}
int ddp[maxn];
void after_bfs4() {
for(int i=1;i<=n;i++) ddp[i] = h[i];
for(int uu=2;uu<=n;uu++) {
int u = sta[uu];
int papa = p[u];
if(u == flag[papa]) {
ddp[u] = max(ddp[u] , dp[papa][1]);
}
else {
ddp[u] = max(ddp[u] , dp[papa][0]);
}
if(u == ff[papa]) {
ddp[u] = max(ddp[u] , g[papa]+k[papa]);

}
else if(u == gg[papa]) {
ddp[u] = max(ddp[u] , f[papa]+k[papa]);
}
else ddp[u] = max(ddp[u] , f[papa]+g[papa]);
}
}
int ans;
void solve() {
bfs();
after_bfs();
after_bfs2();
after_bfs3();
after_bfs4();
ans = (1<<29);
int tm = -1;
for(int u=1;u<=n;u++) {
for(int i=head[u];i!=-1;i=edge[i].next) {
int v = edge[i].v;
if(v == p[u]) continue;
int t1 = max(f[v]+g[v] , dp[v][0]);
int t2 = 0;
if(v == ff[u]) t2 = max(h[u] + g[u] , g[u]+k[u]);
else if(v == gg[u]) t2 = max(h[u]+g[u] , f[u]+k[u]);
else t2 = max(h[u]+g[u] , f[u]+g[u]);
if(v == flag[u]) {
t2 = max(t2 , dp[u][1]);
}
else t2 = max(t2 , dp[u][0]);
t2 = max(t2 , ddp[u]);
//printf("%d and %d 's detail:\n",u,v);
//printf("t1 is %d\n" , t1);
//printf("t2 is %d\n" , t2);
//puts("");
int tt = max(t1 , t2);
if(ans > tt * edge[i].w || ans == tt*edge[i].w && tm > edge[i].id) {
ans = tt*edge[i].w;
tm = edge[i].id;
}
}
}
printf("%d\n" , tm);
}
void debug() {
for(int i=1;i<=n;i++) {
printf("the details of no.%d is\n" , i);
//printf("f is %d\n" , f[i]);
//printf("g is %d\n" , g[i]);
//printf("k is %d\n" , k[i]);
printf("h is %d\n" , h[i]);
//printf("dp[i][0] is %d\n" , dp[i][0]);
//printf("dp[i][1] is %d\n" , dp[i][1]);
//printf("ddp is %d\n" , ddp[i]);
}
}
void debug2() {
for(int i=1;i<=n;i++) {
printf("the father of %d is %d\n" , i , p[i]);
}
}
void debug3() {
for(int i=0;i<E;i++) printf("i   %d\n" , edge[i].id);
}
int main() {
int cas = 1 , T;
scanf("%d" , &T);
while(T--) {
scanf("%d" , &n);
init();
for(int i=1;i<n;i++) {
int u , v , w;
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
edge[E-1].id = edge[E-2].id = i;
}

printf("Case #%d: " , cas++);
solve();
//debug3();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: