树形dp-hdu-3721-Building Roads
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=3721
题目意思:
给一颗树,求移动一条边(边权值不变)到另外的位置,还是一棵树。求最小的树的直径。
解题思路:
充分利用树的直径的性质。
任何点的最远距离一定是树直径上的一个端点。
枚举每条边,分成两颗子树后,求出两颗子树的直径d1,d2,以及两颗树的任意点A的最大距离的最小值p1,p2.显然由树的直径的性质,知点A一定在树的直径上。
ans=min(ans,max(max(d1,d2),p1+p2+len)).
代码:
#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std; #define Maxn 3000
int cnt;
struct Edge
{
int v,len;
struct Edge * next;
}edge[Maxn<<1],*head[Maxn<<1]; void add(int a,int b,int len)
{
++cnt;
edge[cnt].v=b,edge[cnt].len=len;
edge[cnt].next=head[a];
head[a]=&edge[cnt];
}
int ma[Maxn],mi[Maxn];
int Max,Min; void dfs1(int cur,int fa)
{
ma[cur]=mi[cur]=0; struct Edge * p=head[cur];
while(p)
{
int v=p->v; if(v!=fa)
{
dfs1(v,cur);
if(p->len+ma[v]>ma[cur])
{
mi[cur]=ma[cur];
ma[cur]=p->len+ma[v];
}
else if(p->len+ma[v]>mi[cur])
mi[cur]=p->len+ma[v];
}
p=p->next;
}
}
void dfs2(int cur,int fa)
{
if(ma[cur]>Max)
Max=ma[cur];
if(ma[cur]<Min)
Min=ma[cur]; struct Edge * p=head[cur];
while(p)
{
int v=p->v; if(v!=fa)
{
if(p->len+ma[v]<ma[cur]) //最大距离不是从这个儿子过来的
ma[v]=p->len+ma[cur];
else if(p->len+mi[cur]>ma[v]) //最大距离就是这个儿子过来的
ma[v]=p->len+mi[cur];
else if(p->len+mi[cur]>mi[v])
mi[v]=p->len+mi[cur];
dfs2(v,cur);
}
p=p->next;
}
} int main()
{
int t,n; scanf("%d",&t);
for(int ca=1;ca<=t;ca++)
{
scanf("%d",&n); cnt=0;
memset(head,NULL,sizeof(head)); for(int i=1;i<n;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
int ans=INF; //printf("%d\n",cnt);
for(int i=1;i<=cnt;i+=2)
{ //相邻两个编号为一条边
int u=edge[i].v,v=edge[i+1].v,len=edge[i].len;//枚举每一条边
int temp1,temp2; //printf("u:%d v:%d\n",u,v);
Max=0,Min=INF; //Max表示树的直径,Min表示最大距离的最小值
dfs1(u,v);dfs2(u,v); len+=Min;
temp1=Max; Max=0,Min=INF;
dfs1(v,u),dfs2(v,u); //另外一颗子树
//printf(":%d %d\n",Min,Max);
len+=Min;
temp2=Max; len=max(max(temp1,temp2),len);
if(len<ans)
ans=len;
//system("pause");
}
printf("Case %d: %d\n",ca,ans); }
return 0;
}
树形dp-hdu-3721-Building Roads的更多相关文章
- HDU 3721 Building Roads (2010 Asia Tianjin Regional Contest) - from lanshui_Yang
感慨一下,区域赛的题目果然很费脑啊!!不过确实是一道不可多得的好题目!! 题目大意:给你一棵有n个节点的树,让你移动树中一条边的位置,即将这条边连接到任意两个顶点(边的大小不变),要求使得到的新树的直 ...
- fwt优化+树形DP HDU 5909
//fwt优化+树形DP HDU 5909 //见官方题解 // BestCoder Round #88 http://bestcoder.hdu.edu.cn/ #include <bits/ ...
- HDU 1815 Building roads
二分答案 + 2-SAT验证 POJ 稳过,HDU C++ 超时,G++ 550ms左右AC #include<cstdio> #include<cstring> #inclu ...
- HDU - 1054 Strategic Game(二分图最小点覆盖/树形dp)
d.一颗树,选最少的点覆盖所有边 s. 1.可以转成二分图的最小点覆盖来做.不过转换后要把匹配数除以2,这个待细看. 2.也可以用树形dp c.匈牙利算法(邻接表,用vector实现): /* 用ST ...
- 算法笔记--树的直径 && 树形dp && 虚树 && 树分治 && 树上差分 && 树链剖分
树的直径: 利用了树的直径的一个性质:距某个点最远的叶子节点一定是树的某一条直径的端点. 先从任意一顶点a出发,bfs找到离它最远的一个叶子顶点b,然后再从b出发bfs找到离b最远的顶点c,那么b和c ...
- hdu 4123 树形DP+RMQ
http://acm.hdu.edu.cn/showproblem.php? pid=4123 Problem Description Bob wants to hold a race to enco ...
- HDU 4126 Genghis Khan the Conqueror 最小生成树+树形dp
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4126 Genghis Khan the Conqueror Time Limit: 10000/50 ...
- HDU 4123 Bob’s Race 树形dp+单调队列
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4123 Time Limit: 5000/2000 MS (Java/Others) Memory L ...
- HDU 1520 树形dp裸题
1.HDU 1520 Anniversary party 2.总结:第一道树形dp,有点纠结 题意:公司聚会,员工与直接上司不能同时来,求最大权值和 #include<iostream> ...
- HDU 1561 树形DP入门
The more, The Better Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
随机推荐
- OK335xS 256M 512M nand flash make ubifs hacking
/********************************************************************************* * OK335xs 256M 51 ...
- Oracle分页(limit方式的运用)
select * from a_matrix_navigation_map where rowid not in(select rowid from a_matrix_navigation_map w ...
- 很有必要了解的HTML嵌套规则
最近在重新学习HTML的知识,算是对HTML的一个重新认识吧!别小看了这东西,一切的网页可都是以它为基础的!下面就详细归纳一下HTML标签的嵌套规则吧,希望对大家有所帮助. XHTML的标签有许多:d ...
- ThinkPHP3.2 介绍
模块化 驱动化 为云平台而生ThinkPHP3.2正式版发布! ThinkPHP是国内领先的WEB应用开发框架,诞生于2006年初,在国内具有良好的口碑和广大的用户群,秉承了大道至简的开发理念,让WE ...
- if、for、while、do 等语句自占一行
if.for.while.do 等语句自占一行,执行语句不得紧跟其后.不论 执行语句有多少都要加{}.这样可以防止书写失误. #include <iostream> /* run this ...
- (转)MFC的ClistCtrl删除选中多行项目
MFC的ClistCtrl控件添加了多行数据后,若要删除选中的多行数据,可以使用ClistCtrl的成员函数,在网上找了很多例子,发现都有问题,因为在删除ClistCtrl行的时候,删除行下面的行会上 ...
- php -- 取日期
1.获取当前时间方法date()很简单,这就是获取时间的方法, 格式为:date($format, $timestamp), format为格式 - 必需 timestamp为时间戳–可填参数. 比如 ...
- Python下opencv使用笔记(十)(图像频域滤波与傅里叶变换)
前面以前介绍过空间域滤波,空间域滤波就是用各种模板直接与图像进行卷积运算,实现对图像的处理,这个方案直接对图像空间操作,操作简单.所以也是空间域滤波. 频域滤波说究竟终于可能是和空间域滤波实现相同的功 ...
- Python中tab键自动补全功能的配置
新手学习Python的时候,如何没有tab键补全功能,我感觉那将是一个噩梦,对于我们这种菜鸟来说,刚接触python,对一切都不了解,还好有前辈们的指导,学习一下,并记录下来,还没有学习这个功能小伙伴 ...
- u3d性能优化
原文地址:http://blog.csdn.net/molti/article/details/8520418 性能优化需要从多方面入手,大家在项目中遇到的问题还是很普遍的,欢迎大家补充. 图形方面: ...