题意:

There is a city which is built like a tree.A terrorist wants to destroy the city's roads. But now he is alone, he can only destroy one road, then the city will be divided into two cities. Impression
of the city is a number defined as the distance between the farthest two houses (As it relates to the fare).When the terrorist destroyed a road, he needs to spend some energy, assuming that the number is a.At the same time,he will get a number b which is maximum
of the Impression of two cities. The terrorist wants to know which road to destroy so that the product of a and b will be minimized.You should find the road's id.

Note that the length of each road is one.
给出一个树形图,和边权值w代表耗费的能量,每条边的长度是1;破坏一条边<u,v>会形成两棵树,b是两个树中较大的那个直径,a是<u,v>的能量值,求破坏哪条边保证a*b的至最小若存在多个,则输出最先出现的那条边;
分析:求树的直径,我们很容易想到两个dfs可以求出树的直径,所以先树形dp(前两个dfs)求出每个点的正向距离的最大值dis[u][0]和次大值dis[u][1],以及反向距离最大值dis[u][2],然后第三个dfs深搜枚举每条边的两个点<u,v>,对于v点,v所对应的子树的直径就是

dis[v][0]+dis[v][1];

对于v如果belong[u]==v这u所对应的子树的直径是dis[u][1]+dis[u][2];否则对应的子树直径是dis[u][0]+dis[u][2];

然后枚举a*b即可:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#include"queue"
#include"algorithm"
#include"string.h"
#include"string"
#include"math.h"
#include"vector"
#include"stack"
#include"map"
#define eps 1e-4
#define inf 0x3f3f3f3f
#define M 100009
#define PI acos(-1.0)
using namespace std;
struct node
{
int u,v,w,next;
}edge[M*2];
int t,head[M],dis[M][4],length[M*2],belong[M];
__int64 ans,num[M],n;
void init()
{
t=0;
memset(head,-1,sizeof(head));
}
void add(int u,int v,int w)
{
edge[t].u=u;
edge[t].v=v;
edge[t].w=w;
edge[t].next=head[u];
head[u]=t++;
}
void dfs(int u,int f)
{
dis[u][0]=dis[u][1]=dis[u][2]=0;
for(int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].v;
if(v==f)continue;
dfs(v,u);
if(dis[u][0]<dis[v][0]+1)
{
dis[u][1]=dis[u][0];
dis[u][0]=dis[v][0]+1;
belong[u]=v;
}
else if(dis[u][1]<dis[v][0]+1)
dis[u][1]=dis[v][0]+1;
}
}
void dfs1(int u,int f)
{
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(v==f)
continue;
if(belong[u]==v)
dis[v][2]=max(dis[u][1],dis[u][2])+1;
else
dis[v][2]=max(dis[u][0],dis[u][2])+1;
dfs1(v,u);
}
}
void dfs2(int u,int f)
{
for(int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].v;
if(v==f)continue;
if(belong[u]==v)
{
length[i]=dis[v][0]+dis[v][1];
length[i^1]=dis[u][1]+dis[u][2];
}
else
{
length[i]=dis[v][0]+dis[v][1];
length[i^1]=dis[u][0]+dis[u][2];
}
dfs2(v,u);
}
}
int main()
{
int Case,i,n,a,b,c,kk=1;
scanf("%d",&Case);
while(Case--)
{
scanf("%d",&n);
init();
for(i=1;i<n;i++)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
dfs(1,-1);
dfs1(1,-1);
dfs2(1,-1);
ans=inf;
int id;
for(i=0;i<t;i+=2)
{
//printf("%d %d %d %d\n",edge[i].u,edge[i].v,length[i],length[i^1]);
int m=max(length[i],length[i^1])*edge[i].w;
if(ans>m)
{
id=i;
ans=m;
}
}
printf("Case #%d: %d\n",kk++,(id+2)/2);
}
}


树形DP 2013多校8(Terrorist’s destroy HDU4679)的更多相关文章

  1. hdu4705 Y 简单树形DP 2013多校训练第十场 J题

    题意:求一棵树中不在一条链中的三个点的对数. 转化一下,用总对数减去在一条链上的三点对数即可. 考虑经过根节点,然后可能是不同的子树中各选一个:或者是子树中选一个,然后当前节点为根的子树以外的节点选一 ...

  2. hdu4681 String DP(2013多校第8场)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4681 思路: 我是胡搞过的 就是先预处理出(i,j)的正向的最大连续子串和逆向最大连续子串 然后对于A ...

  3. 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 ...

  4. HDU 4705 Y (2013多校10,1010题,简单树形DP)

    Y Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submiss ...

  5. HDU4612(Warm up)2013多校2-图的边双连通问题(Tarjan算法+树形DP)

    /** 题目大意: 给你一个无向连通图,问加上一条边后得到的图的最少的割边数; 算法思想: 图的边双连通Tarjan算法+树形DP; 即通过Tarjan算法对边双连通缩图,构成一棵树,然后用树形DP求 ...

  6. HDU 4681 String(2013多校8 1006题 DP)

    String Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Subm ...

  7. HDU-4679 Terrorist’s destroy 树形DP,维护

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4679 题意:给一颗树,每个边有一个权值,要你去掉一条边权值w剩下的两颗子树中分别的最长链a,b,使得w ...

  8. HDU-6035 Colorful Tree(树形DP) 2017多校第一场

    题意:给出一棵树,树上的每个节点都有一个颜色,定义一种值为两点之间路径中不同颜色的个数,然后一棵树有n*(n-1)/2条 路径,求所有的路径的值加起来是多少. 思路:比赛的时候感觉是树形DP,但是脑袋 ...

  9. hdu 6035:Colorful Tree (2017 多校第一场 1003) 【树形dp】

    题目链接 单独考虑每一种颜色,答案就是对于每种颜色至少经过一次这种的路径条数之和.反过来思考只需要求有多少条路径没有经过这种颜色即可. 具体实现过程比较复杂,很神奇的一个树形dp,下面给出一个含较详细 ...

随机推荐

  1. var wi = 0; wi < arr.length; wi++

    思维 <?php$w = 123;$wb = $w;$w = 456;echo $wb;?><script type="text/javascript">  ...

  2. java编程算法

    一.字符串相关操作 String s = " Hello java,hello android,hello OOP,HELLO String,hello JAVASE!"; Sys ...

  3. springMVC配置文件spring-servlet.xml中<mvc:annotation-driven />的意义

    <mvc:annotation-driven/>标签,对应的实现类是org.springframework.web.servlet.config.AnnotationDrivenBeanD ...

  4. NRF51822之GPIOTE使用

    ---恢复内容开始--- 在上篇介绍nrf51822的GPIOTE http://www.cnblogs.com/libra13179/p/5336580.html 我们现在开始下水游泳. /** @ ...

  5. 深入理解Linux中内存管理

    前一段时间看了<深入理解Linux内核>对其中的内存管理部分花了不少时间,但是还是有很多问题不是很清楚,最近又花了一些时间复习了一下,在这里记录下自己的理解和对Linux中内存管理的一些看 ...

  6. C/C++程序编译流程(预处理->编译->汇编->链接)

    程序的基本流程如图: 1. 预处理 预处理相当于根据预处理指令组装新的C/C++程序.经过预处理,会产生一个没有宏定义,没有条件编译指令,没有特殊符号的输出文件,这个文件的含义同原本的文件无异,只是内 ...

  7. [LeetCode] Simplify Path(可以不用看)

    Given an absolute path for a file (Unix-style), simplify it. For example, path = "/home/", ...

  8. mysqlnd cannot connect to MySQL 4.1+ using the old insecure authentication解决办法

    mysqlnd是个好东西.不仅可以提高与mysql数据库通信的效率,而且也可以方便的设置一些超时.如,连接超时,查询超时.但是,使用mysqlnd的时候,有个地方需要注意.就是服务端的密码格式不能使用 ...

  9. (转帖) java内存分配分析/栈内存、堆内存

    http://blog.csdn.net/qh_java/article/details/9084091

  10. OC的内存管理

    摘自:http://blog.csdn.net/hahahacff/article/details/39839571 OC内存管理 一.基本原理 (一)为什么要进行内存管理. 由于移动设备的内存极其有 ...