树形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 ...
随机推荐
- 【WPF】样式与模板:鼠标移入/悬浮时按钮的背景色不改变
情况:鼠标移到按钮上,默认情况是按钮背景色会改变的,网上也能搜到很多如何自定义改变的背景色. 需求:现在需求反过来,想要鼠标移到按钮上,保持按钮的背景色不改变. 一种思路:在样式文件中,使用Multi ...
- Android——用对话框做登陆界面(自定义对话框AlertDialog,多线程,进度条ProgressDialog,ListView,GridView,SharedPreferences存,读数据,存取文本,assets文件)
效果: 1.点击图标进入页面二 2.页面2图片暂停显示5秒进入页面三 3.点击页面三登陆按钮,打开登陆对话框,输入密码进入页面四 点击下载按钮,显示水平进度条 点击保存和获取用户名和密码 进入页面六 ...
- 双行表头DatagridView的简单实现
DatagridView默认不支持多行表头的实现,一些第三方的控件,比如Spread就可以,因此要实现这个功能,只能自己想办法了.介绍两种思路:1,用重写DataGridView的Paint等方法,可 ...
- java-事务-案例
项目结构: 数据库: /* SQLyog Ultimate v12.09 (64 bit) MySQL - 5.5.53 : Database - threadlocal ************** ...
- DIV内滚动条滚动到指定位置
相对浏览器,将指定div滚到到指定位置,其用法如下: $("html,body").animate({scrollTop: $(obj).offset().top},speed); ...
- 使用伪hash降低索引长度
理想的索引 1:查询频繁 2:区分度高 3:长度小 4: 尽量能覆盖常用查询字段. 1: 索引长度直接影响索引文件的大小,影响增删改的速度,并间接影响查询速度(占用内存多). 针对列中的值,从左往 ...
- IE屏蔽鼠标右键、禁止复制粘贴等功能
<body oncontextmenu="return false" onselectstart="return false" ondragstart=& ...
- 配置 -- PHPstorm+Xdebug断点调试PHP
运行环境: PHPSTORM版本 : 8.0.1 PHP版本 : 5.6.2 xdebug版本:php_xdebug-2.2.5-5.6-vc11-x86_64.dll ps : php版本和xdeb ...
- R语言低级绘图函数-symbols
严格意义上将symbols 并不能算是一个低级的绘图函数,因为它不仅可以在一幅已经存在的图标上添加元素,还可以创建一张新的图表 鉴于它绘图时的灵活性,我把它归入到低级绘图函数中 symbols 可以创 ...
- Java 基本概念:jvm、jdk、jre、jse
jvm 是java虚拟机,将java的class字节码文件翻译成二进制可执行程序.jdk 是java的开发包 Javasdk, java的开发工具,包含SUN公司提供的javaAPI,将java源码编 ...