hdu 4679 Terrorist’s destroy 树形DP
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4679
题意:给定一颗树,每条边有一个权值w,问切掉哪条边之后,分成的两颗树的较大的直径*切掉边的权值最小?如果存在多条边使得结果相同,输出边id最小的
思路:
dept一次找出最深的节点,之后以最深的节点出发(rt1)dept找到树的直径(即找到rt2);将路径保存在f[]中;
之后分别从rt1/rt2进行深搜,找到以一个节点为根的树的直径,这样在每次dfs之后,可以求出每条边的一边的最值,这样两次取max之后就求出了切掉该边之后得到的结果
注:
如果改变在整棵树的直径上,需要取出以该棵树为根的树的直径maxn[0][v];否则就直接取整棵树的直径即可;
在dfs递推出以某根为子树的直径时,可能直径不过根节点所以要将子子树的直径递推到子树上;
#include<bits/stdc++.h>
#pragma comment(linker, "/STACK:1024000000,1024000000") //加栈
using namespace std;
#define rep0(i,l,r) for(int i = (l);i < (r);i++)
#define rep1(i,l,r) for(int i = (l);i <= (r);i++)
#define rep_0(i,r,l) for(int i = (r);i > (l);i--)
#define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
#define MS0(a) memset(a,0,sizeof(a))
#define MS1(a) memset(a,-1,sizeof(a))
#define MSi(a) memset(a,0x3f,sizeof(a))
#define inf 0x3f3f3f3f
#define lson l, m, rt << 1
#define rson m+1, r, rt << 1|1
typedef pair<int,int> PII;
#define A first
#define B second
#define MK make_pair
typedef long long ll;
typedef unsigned int uint;
template<typename T>
void read1(T &m)
{
T x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
m = x*f;
}
template<typename T>
void read2(T &a,T &b){read1(a);read1(b);}
template<typename T>
void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);}
template<typename T>
void out(T a)
{
if(a>) out(a/);
putchar(a%+'');
}
#define N 100007
int head[N<<],tot;
struct edge{
int to,w,id,Next;
}e[N<<];
void ins(int a,int b,int w,int id)
{
e[++tot].Next = head[a];
e[tot].to = b;
e[tot].w = w;
e[tot].id = id;
head[a] = tot;
}
int dep[N],p[N];
void dept(int u,int pre)
{
p[u] = pre;
dep[u] = dep[pre] + ;
for(int id = head[u];id;id = e[id].Next){
int v = e[id].to;
if(v == pre) continue;
dept(v,u);
}
}
int f[N],maxlen;//树的直径
int aux[N];
int maxn[][N];
void dfs(int u,int pre)
{
maxn[][u] = maxn[][u] = maxn[][u] = ;
for(int id = head[u];id;id = e[id].Next){
int v = e[id].to;
if(v == pre) continue;
dfs(v,u);
if(maxn[][u] <= maxn[][v]+){
maxn[][u] = maxn[][u];
maxn[][u] = maxn[][v]+;
}else if(maxn[][u] < maxn[][v]+)
maxn[][u] = maxn[][v]+;
if(maxn[][u] < maxn[][v]) //**可能树的直径不过根节点;
maxn[][u] = maxn[][v];
}
maxn[][u] = max(maxn[][u],maxn[][u] + maxn[][u]); //以u为根的子树的直径
}
void solve(int u,int pre)
{
for(int id = head[u];id;id = e[id].Next){
int v = e[id].to, w = e[id].w;
if(v == pre) continue;
if(f[u] && f[v]){ //边在直径上
aux[e[id].id] = max(aux[e[id].id],w*maxn[][v]);
}else{
aux[e[id].id] = max(aux[e[id].id],w*maxlen);
}
solve(v,u);
}
}
int main()
{
//freopen("data.txt","r",stdin);
//freopen("out.txt","w",stdout);
int kase = ,T,n;
read1(T);
while(T--){
MS0(head);tot = ;
MS0(f);
read1(n);
rep0(i,,n){
int u,v,w;
read3(u,v,w);
ins(u,v,w,i);ins(v,u,w,i);
}
dep[] = ;
dept(,);
int rt1 ,rt2 ,d = ;
rep1(i,,n) if(d < dep[i]) d = dep[i],rt1 = i;
dept(rt1,);
d = ;
rep1(i,,n) if(d < dep[i]) d = dep[i],rt2 = i;
maxlen = d-; //求出树的直径;以及两端的节点标号
int index = rt2;
while(index){
f[index] = ;
index = p[index]; //从树直径的终点递推到起点
}
MS0(aux);
dfs(rt1,-);
solve(rt1,);
dfs(rt2,-);
solve(rt2,);
int ans = inf;
rep0(i,,n){
if(ans > aux[i]) ans = aux[i],index = i;
}
printf("Case #%d: %d\n",kase++,index);
}
return ;
}
hdu 4679 Terrorist’s destroy 树形DP的更多相关文章
- 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 ...
- HDU-4679 Terrorist’s destroy 树形DP,维护
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4679 题意:给一颗树,每个边有一个权值,要你去掉一条边权值w剩下的两颗子树中分别的最长链a,b,使得w ...
- hdu 4679 Terrorist’s destroy 树的直径+dp
题意:给你一棵树,每条边都有值W,然后问你去掉一条边,令val = w*max(两颗新树的直径),求val最小值~ 做法,先求树的直径,然后算出直径上每个点的最长枝条长度.这样对于每一条边,假如是枝条 ...
- HDU 4679 Terrorist’s destroy
如果不在最长路的边,那么肯定是w*最长路. 如果在最长路,那么把最长路分成两段,左边树的最长路就是左段+左边点的次短路(不包含最长路上的点的最长路) ,右边同理. 还有就是更新,经过左端点的最长路,不 ...
- hdu 4514 并查集+树形dp
湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Tot ...
- [HDU 5293]Tree chain problem(树形dp+树链剖分)
[HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...
- HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...
- hdu 4003 Find Metal Mineral 树形DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4003 Humans have discovered a kind of new metal miner ...
- HDU 5758 Explorer Bo(树形DP)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5758 [题目大意] 给出一棵树,每条路长度为1,允许从一个节点传送到任意一个节点,现在要求在传送次 ...
随机推荐
- Android进阶笔记15:ListView篇之图片优化
1.图片异步加载: (1)处理图片的方式: 如果ListView中自定义的Item中有涉及到大量图片的,一定要对图片进行细心的处理,因为图片占的内存是 ListView 项中最头疼的,处理图片的方法大 ...
- oracle的控制语句if和循环语句loop while for
pl/sql的控制结构if-then if-then-else if-then-elsif-else 案例1:编写一个过程,可以输入一个雇员名,如果该雇员的工资低于2000,就给该雇员工资增加10% ...
- javaweb学习总结十九(http协议概述以及http请求信息分析)
一:http协议概述 1:http协议定义 2:使用telnet程序连接web服务器,获取资源 3:http协议:超文本传输协议,它是基于tcp/ip协议,就是建立在tcp/ip之上工作的, http ...
- xml版本学生管理系统
一: 需求描述 学生成绩管理系统,使用xml存储学生信息,可以对学生信息进行增.删.删除操作. 主要目的:练习操作xml元素的增删改查 二:代码结构 1:xml存储数据如下 exam.xml < ...
- poj 1185 炮兵阵地 状态压缩dp
思路:定义一个三维数组dp[x][i][j]其中x为now和pre两种状态,now表示当前两行最优解,pre表示出了本行外,前两行的最优解.那么状态转移方程为 dp[now][j][k]=max(dp ...
- input两种默认显示文字方式
First Note: placeholder属性 规定帮助用户填写输入字段的提示,值不会被提交, 且该提示会在输入字段为空时显示,并会在字段获得焦点时消失. 如 <input type=&qu ...
- [译]脱离jQuery,使用原生Ajax
脱离jQuery,使用原生Ajax 标签: Ajax translate 英文出处:<A Guide to Vanilla Ajax Without jQuery> 翻译: 刘健超 J.c ...
- 从零单排Linux – 2 – 目录权限
从零单排Linux – 2 – 目录权限 1.sync 讲内存数据跟新到硬盘中 2.执行等级init a: run level 0:关机 b: run level 3:纯命令模式 c:run leve ...
- HTTP - 基本认证
有数百万的人在用 Web 进行私人事务处理,访问私有的数据.通过 Web 可以很方便地访问这些信息,但是仅仅是方便访问还是不够的.我们要保证只有特定的人能看到我们的敏感信息并且能够执行我们的特权事务. ...
- 第一章、C#委托和事件(Delegate、Event、EventHandler、EventArgs)
第一章.C#委托和事件(Delegate.Event.EventHandler.EventArgs) 分类: 学习笔记-C#网络编程2012-12-08 14:10 7417人阅读 评论(3) 收藏 ...