题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4679

  题意:给一颗树,每个边有一个权值,要你去掉一条边权值w剩下的两颗子树中分别的最长链a,b,使得w*Min(a,b)最小。。

  说白了就是要枚举每条边,然后在O(1)的时间内求出两颗子树的最长链。因此我们可以考虑用树形DP,首先一遍DFS,对于每个节点维护两个信息,hign[u]:u为根节点的子树的深度,f[u]:u为根节点的子树的最长链。然后还要维护一个hige[i][0]和hige[i][1],分别表示u为根节点的子树,不包括边 i 的深度和最长链。然后再一遍DFS,根据上一节点的信息递推过去就可以在O(1)的时间内求出来了,总复杂度O(E)。有些细节要考虑,开始把全局变量搞混,wa了几次T^T。。

 //STATUS:C++_AC_875MS_11012KB
#include <functional>
#include <algorithm>
#include <iostream>
//#include <ext/rope>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <numeric>
#include <cstring>
#include <cassert>
#include <cstdio>
#include <string>
#include <vector>
#include <bitset>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <list>
#include <set>
#include <map>
using namespace std;
#pragma comment(linker,"/STACK:102400000,102400000")
//using namespace __gnu_cxx;
//define
#define pii pair<int,int>
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define PI acos(-1.0)
//typedef
typedef __int64 LL;
typedef unsigned __int64 ULL;
//const
const int N=1;
const int INF=0x3f3f3f3f;
const LL MOD=,STA=;
const LL LNF=1LL<<;
const double EPS=1e-;
const double OO=1e50;
const int dx[]={-,-,,,,,,-};
const int dy[]={,,,,,-,-,-};
const int day[]={,,,,,,,,,,,,};
//Daily Use ...
inline int sign(double x){return (x>EPS)-(x<-EPS);}
template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
template<class T> inline T lcm(T a,T b,T d){return a/d*b;}
template<class T> inline T Min(T a,T b){return a<b?a:b;}
template<class T> inline T Max(T a,T b){return a>b?a:b;}
template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);}
template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);}
template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));}
template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));}
//End struct Edge{
int u,v,w,id;
}e[N<<];
int first[N],next[N<<],hign[N],hige[N<<][];
int f[N],maxl1[N],maxr1[N],maxl2[N],maxr2[N],maxlf[N],maxrf[N],d[N],w[N];
int n,mt;
int T,ans,ansid; void adde(int a,int b,int c,int id)
{
e[mt].u=a,e[mt].v=b,e[mt].w=c,e[mt].id=id;
next[mt]=first[a];first[a]=mt++;
e[mt].u=b,e[mt].v=a,e[mt].w=c,e[mt].id=id;
next[mt]=first[b];first[b]=mt++;
} void dfs1(int u,int fa)
{
int i,j,v,cnt=,flag=;
f[u]=;
for(i=first[u];i!=-;i=next[i]){
if((v=e[i].v)==fa)continue;
dfs1(v,u);
f[u]=Max(f[u],f[v]);
flag=;
}
if(!flag){f[u]=hign[u]=;return;}
for(i=first[u];i!=-;i=next[i]){
if((v=e[i].v)==fa)continue;
w[cnt]=v;
d[cnt++]=hign[v]+;
}
maxl1[]=maxr1[cnt]=maxl2[]=maxr2[cnt]=maxlf[]=maxrf[cnt]=;
for(i=;i<cnt;i++){
maxlf[i]=Max(maxlf[i-],f[w[i]]);
maxl1[i]=maxl1[i-],maxl2[i]=maxl2[i-];
if(d[i]>maxl1[i])maxl2[i]=maxl1[i],maxl1[i]=d[i];
else if(d[i]>maxl2[i])maxl2[i]=d[i];
}
for(i=cnt-;i>;i--){
maxrf[i]=Max(maxrf[i+],f[w[i]]);
maxr1[i]=maxr1[i+],maxr2[i]=maxr2[i+];
if(d[i]>maxr1[i])maxr2[i]=maxr1[i],maxr1[i]=d[i];
else if(d[i]>maxr2[i])maxr2[i]=d[i];
}
for(j=,i=first[u];i!=-;i=next[i]){
if(e[i].v==fa)continue;
hige[i][]=Max(maxl1[j-],maxr1[j+]);
hige[i][]=Max(maxl1[j-]+maxr1[j+],
maxl1[j-]+maxl2[j-],maxr1[j+]+maxr2[j+]);
hige[i][]=Max(hige[i][],maxlf[j-],maxrf[j+]);
j++;
}
f[u]=Max(f[u],maxr1[]+maxr2[]);
hign[u]=maxr1[];
} void dfs2(int u,int fa,int max1,int max2)
{
int i,j,v,t1,t2,nt;
for(i=first[u];i!=-;i=next[i]){
if((v=e[i].v)==fa)continue;
t1=Max(hige[i][],max2,max1+hige[i][]);
nt=Max(f[v],t1)*e[i].w;
if(ans>nt || (ans==nt && e[i].id<ansid)){
ans=nt;
ansid=e[i].id;
}
t2=Max(max1,hige[i][])+;
dfs2(v,u,t2,Max(t1,t2));
}
} int main(){
// freopen("in.txt","r",stdin);
int i,j,a,b,c,ca=;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
mem(first,-);mt=;
for(i=;i<n;i++){
scanf("%d%d%d",&a,&b,&c);
adde(a,b,c,i);
} dfs1(,);
ans=INF;
dfs2(,,,); printf("Case #%d: %d\n",ca++,ansid);
}
return ;
}

HDU-4679 Terrorist’s destroy 树形DP,维护的更多相关文章

  1. hdu 4679 Terrorist’s destroy 树形DP

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4679 题意:给定一颗树,每条边有一个权值w,问切掉哪条边之后,分成的两颗树的较大的直径*切掉边的权值最小? ...

  2. HDU 4679 Terrorist’s destroy (2013多校8 1004题 树形DP)

    Terrorist’s destroy Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Othe ...

  3. hdu 4679 Terrorist’s destroy 树的直径+dp

    题意:给你一棵树,每条边都有值W,然后问你去掉一条边,令val = w*max(两颗新树的直径),求val最小值~ 做法,先求树的直径,然后算出直径上每个点的最长枝条长度.这样对于每一条边,假如是枝条 ...

  4. HDU 4679 Terrorist’s destroy

    如果不在最长路的边,那么肯定是w*最长路. 如果在最长路,那么把最长路分成两段,左边树的最长路就是左段+左边点的次短路(不包含最长路上的点的最长路) ,右边同理. 还有就是更新,经过左端点的最长路,不 ...

  5. [HDU 5293]Tree chain problem(树形dp+树链剖分)

    [HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...

  6. hdu 4514 并查集+树形dp

    湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tot ...

  7. HDU 4123 (2011 Asia FZU contest)(树形DP + 维护最长子序列)(bfs + 尺取法)

    题意:告诉一张带权图,不存在环,存下每个点能够到的最大的距离,就是一个长度为n的序列,然后求出最大值-最小值不大于Q的最长子序列的长度. 做法1:两步,第一步是根据图计算出这个序列,大姐头用了树形DP ...

  8. HDU 4123 Bob’s Race 树形dp+单调队列

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4123 Time Limit: 5000/2000 MS (Java/Others) Memory L ...

  9. HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...

随机推荐

  1. Unity3d + NGUI 的多分辨率适配(黑边)

    原地址:http://www.2cto.com/kf/201310/250921.html 一.当下移动设备的主流分辨率(数据来自“腾讯分析移动设备屏幕分辨率分析报告”) 1.1 iOS设备的分辨率主 ...

  2. Otto开发初探——微服务依赖管理新利器

    [编者按]时下,Vagrant 被 DevOps 软件开发商广泛作为开发阶段的本地软件开发环境,而在本文,CERT Division高级研究员介绍的 Otto 则是 Vagrant 开发团队 Hash ...

  3. HDU1569+最大点权集

    /* 最大点权独立集=总权值-最小点权覆盖集 最大点权独立集=最大流 最小点权覆盖集=最小割 题意: 给你一个m*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格 ...

  4. 2013 Multi-University Training Contest 5 k-th point

    刚开始我也不知道怎么做,后来慢慢就推出来了…… 对于样例 2 1 0,结果是2/3 2 2 0,结果是4/5 3 2 0,结果是6/7 3 2 1,结果是9/14=6/7*3/4 …… 之后就会发现每 ...

  5. 嵌入式开发之NorFlash 和NandFlash

    http://blog.csdn.net/tigerjibo/article/details/9322035 [摘要]:作为一个嵌入式工程师,要对NorFlash 和NandFlash要有最起码的认知 ...

  6. Ubuntu中安装DiscuzX2

    http://blog.csdn.net/kevin_ysu/article/details/7452938 一.Apache的安装 Apache作为一个功能强大的Web程序,自然是架建Web服务器的 ...

  7. MyEclipse下查看Java API帮助文档

    每次重装JDK或者升级JDK时,都会忘了如何使MyEclipse关联帮助文档.然后,再花十几分钟重新google搜索,麻烦! 首先下载Javadoc api帮助文档,google搜一下就行了. MyE ...

  8. 万网空间如何安装wordpress

    万网空间如何安装wordpress建站教程 _ 学做网站论坛 http://www.xuewangzhan.com/wpbbs/1643.html   1.先在本地下载一个最新版本的wordpress ...

  9. 理解 PHP 中的 Streams

    Streams 是PHP提供的一个强有力的工具,我们常常在不经意会使用到它,如果善加利用将大大提高PHP的生产力. 驾驭Streams的强大力量后,应用程序将提升到一个新的高度. 下面是PHP手册中对 ...

  10. 【HDOJ】4326 Game

    1. 题目描述一个长度为n个队列,每次取队头的4个人玩儿游戏,每个人等概率赢得比赛.胜者任然处在队头,然而败者按照原顺序依次排在队尾.连续赢得m场比赛的玩家赢得最终胜利.求第k个人赢得最终胜利的概率. ...