思路:我们其实只需要枚举每条边,求得最小值就行了。

先dfs算出每个节点作为根时,其子树的最长路径,以及进过该节点的最长,次长,第三长路径。

然后在次dfs枚举求出切断某条边,求出这条边的两个端点为子树根,其子树的最长路径。b就是其中较大的。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<vector>
#define Maxn 200010
using namespace std;
int road[Maxn],Max[Maxn],lMax[Maxn],vi[Maxn],e,head[Maxn],dis[Maxn],ldis[Maxn],pr,ans,sMax[Maxn],lroad[Maxn];
struct Edge{
int u,v,val,id,next;
}edge[Maxn*];
void init()
{
memset(road,,sizeof(road));
memset(Max,,sizeof(Max));
memset(lMax,,sizeof(lMax));
memset(vi,,sizeof(vi));
memset(dis,,sizeof(dis));
memset(ldis,,sizeof(ldis));
memset(head,-,sizeof(head));
memset(sMax,,sizeof(sMax));
memset(lroad,,sizeof(lroad));
e=;
}
void add(int u,int v,int val,int id)
{
edge[e].u=u,edge[e].v=v,edge[e].val=val,edge[e].id=id,edge[e].next=head[u],head[u]=e++;
edge[e].u=v,edge[e].v=u,edge[e].val=val,edge[e].id=id,edge[e].next=head[v],head[v]=e++;
}
void dfs(int u)
{
int i,v;
vi[u]=;
for(i=head[u];i!=-;i=edge[i].next)
{
v=edge[i].v;
if(vi[v]) continue;
dfs(v);
if(Max[v]+>Max[u])
{
sMax[u]=lMax[u];
lroad[u]=road[u];
lMax[u]=Max[u];
Max[u]=Max[v]+;
road[u]=v;
}
else
if(Max[v]+>lMax[u])
{
sMax[u]=lMax[u];
lMax[u]=Max[v]+;
lroad[u]=v;
}
dis[u]=max(dis[u],Max[u]+lMax[u]);
dis[u]=max(dis[u],dis[v]);
}
}
void predfs(int u,int d,int pre,int fa)
{
int i,v;
vi[u]=;
int now=;
int a,b=;
for(i=head[u];i!=-;i=edge[i].next)
{
v=edge[i].v;
if(vi[v]) continue;
a=edge[i].val;
now=pre;
if(road[u]==v)
{
now=max(d+lMax[u],now);
now=max(lMax[u]+sMax[u],now);
b=max(now,dis[v]);
if(a*b<=pr)
{
if(a*b==pr)
{
if(edge[i].id<ans)
ans=edge[i].id;
}
else
pr=a*b,ans=edge[i].id;
}
predfs(v,max(d,lMax[u])+,now,u);
}
else
if(lroad[u]==v)
{
now=max(d+Max[u],now);
now=max(Max[u]+sMax[u],now);
b=max(now,dis[v]);
if(a*b<=pr)
{
if(a*b==pr)
{
if(edge[i].id<ans)
ans=edge[i].id;
}
else
pr=a*b,ans=edge[i].id;
}
predfs(v,max(d,Max[u])+,now,u);
}
else
{
now=max(d+Max[u],now);
now=max(Max[u]+lMax[u],now);
b=max(now,dis[v]);
if(a*b<=pr)
{
if(a*b==pr)
{
if(edge[i].id<ans)
ans=edge[i].id;
}
else
pr=a*b,ans=edge[i].id;
}
predfs(v,max(d,Max[u])+,now,u);
}
}
}
int main()
{
int n,i,j,m,t,u,v,w,Case=;
scanf("%d",&t);
while(t--)
{
init();
scanf("%d",&n);
for(i=;i<=n-;i++)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w,i);
}
int a,b;
dfs();
memset(vi,,sizeof(vi));
pr=;
ans=;
predfs(,,,);
printf("Case #%d: %d\n",++Case,ans);
}
return ;
}

hdu 4679 树状dp的更多相关文章

  1. hdu 4582 树状DP

    思路:首先声明我是参考:http://blog.csdn.net/frog1902/article/details/9921845这位大牛的博客的. 他说的已经很详尽,但我还是要补充几点. 看完他的解 ...

  2. hdu 4340 树状DP

    思路:我们定义两个数组,ant[Maxn][2],bob[Maxn][2].ant[i][0]表示还未确定哪个城市被全费用占领,ant[i][1]表示确定了哪个城市被全费用占领.那么ant[i][0] ...

  3. HDU 4035Maze(树状+概率dp,绝对经典)

    题意: 给你n个节点的树,从1节点开始走,到每个节点都有三种情况,被杀死回到1节点,找到隐藏的出口出去,沿着当前节点相邻的边走到下一个节点,给出每个节点三种情况发生的概率分别为ki,ei,1-ki-e ...

  4. hdu 1561 The more, The Better_树状dp

    题目链接 题意:给你一棵树,各个节点都有价值(除根节点),从根节点出发,选择m个节点,问最多的价值是多小. 思路:很明显是树状dp,遍历树时背包最优价值,dp[i][k]=max{dp[i][r]+d ...

  5. HDU 4714 Tree2cycle(树状DP)(2013 ACM/ICPC Asia Regional Online ―― Warmup)

    Description A tree with N nodes and N-1 edges is given. To connect or disconnect one edge, we need 1 ...

  6. 树状DP HDU1520 Anniversary party

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1520 题意:职员之间有上下级关系,每个职员有自己的happy值,越高在派对上就越能炒热气氛.但是必须是 ...

  7. 树状DP (poj 2342)

    题目:Anniversary party 题意:给出N各节点的快乐指数,以及父子关系,求最大快乐指数和(没人职员愿意跟直接上司一起玩): 思路:从底向上的树状DP: 第一种情况:第i个员工不参与,F[ ...

  8. poj3659树状DP

    Cell Phone Network Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6273   Accepted: 225 ...

  9. poj 2342 Anniversary party_经典树状dp

    题意:Ural大学有n个职员,1~N编号,他们有从属关系,就是说他们关系就像一棵树,父节点就是子节点的直接上司,每个职员有一个快乐指数,现在要开会,职员和职员的直接上司不能同时开会,问怎才能使开会的快 ...

随机推荐

  1. codeforces 652B z-sort(思维)

    B. z-sort time limit per test 1 second memory limit per test 256 megabytes input standard input outp ...

  2. Linux下的进程管理

    在操作系统系统中,进程是一个非常重要的概念. 一.Linux中进程的相关知识 1.什么是进程呢? 通俗的来说进程是运行起来的程序.唯一标示进程的是进程描述符(PID),在linux内核中是通过task ...

  3. HDU 5832 A water problem (水题,大数)

    题意:给定一个大数,问你取模73 和 137是不是都是0. 析:没什么可说的,先用char 存储下来,再一位一位的算就好了. 代码如下: #pragma comment(linker, "/ ...

  4. 模板引擎doT.js介绍及如何判断对象为空、如何嵌套循环···

    doT.js 灵感来源于搜寻基于 V8 和 Node.js ,强调性能,最快速最简洁的 JavaScript 模板函数 引入 javascript 文件: <script type=" ...

  5. 【Python3】SMTP发送邮件

    犹豫和反复浪费了大量时间. 与朋友言 在完成一个邮件发送程序之前我根本不明白什么是邮件,哪怕已经读过廖雪峰大神的文章,没有贬低大神的意思,大神的博客已经非常的详细, 是我的眼大肚皮小毛病在作祟,由一个 ...

  6. CF:322D - Ciel and Duel 贪心 或者 DP 我用的贪心 。。难道sort跟qsort是不一样的么?

    D. Ciel and Duel time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  7. stl lower_bound upper_bound binary_search equal_range

    自己按照stl实现了一个:   http://www.cplusplus.com/reference/algorithm/binary_search/ 这里有个注释,如何判断两个元素相同: Two e ...

  8. strutx.xml中配置文件的讲解

    Struts2框架的核心就是struts.xml文件了,该文件主要负责管理Struts的2的业务控制组件的核心内容.为了避免struts.xml的文件国 语庞大和臃肿,我们可以通过把一个struts. ...

  9. ios开发——仿新版iBooks书本打开与关闭动画

    IOS新版iBooks吸引人的地方除了有干净整洁的界面.方便灵活的操作以及大容量的书籍容量以外.还有其优秀的用户交互,尤其是其动画的使用.打开一本书时书本缓慢放大并打开.关闭一本书后书本关闭并回到原位 ...

  10. ios开发——实用技术篇Swift篇&地址薄、短信、邮件

    //返回按钮事件 @IBAction func backButtonClick() { self.navigationController?.popViewControllerAnimated(tru ...