树形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 ...
随机推荐
- wso2as安装
1.系统环境 Ubuntu12.04 192.168.0.97 root/password找管理员 Ubuntu12.04 192.168.0.99 root/password ...
- Springboot 之 Hibernate自动建表(Mysql)
Springboot 之 Hibernate自动建表(Mysql) 2016年10月21日 10:39:44 阅读数:8180 本文章来自[知识林] 引入Maven依赖包 <dependency ...
- 06 Locking and Latching
本章提要---------------------------------------------------------------6,7,8,9,10,11 这 6 章要细看, 从本章开始how ...
- openfire安装配置完全教程
Java领域的IM解决方案 Java领域的即时通信的解决方案可以考虑openfire+spark+smack. Openfire是基于Jabber协议(XMPP)实现的即时通信服务器端,最新版本是3. ...
- 关于Cocos2d-x运行项目时弹框崩溃的解决
想要运行工程的时候,跳出一个框说停止cantnot open the window,还提到什么GLVM之类的,这是显卡驱动出现问题,如果是远程连接电脑的话,很有可能就是用来远程连接的那台电脑的显卡驱动 ...
- python + opencv: kalman 跟踪
之前博文中讲解过kalman滤波的原理和应用,这里用一个跟踪鼠标的例程来演示怎么在opencv里用自带的kalman函数进行目标跟踪,文章的内容对做图像跟踪有借鉴意义.文章主要是网络资源进行整理和简单 ...
- TF42064: The build number already exists for build definition error in TFS2010
In TFS2008, deleting a build removes it from the database itself. If you delete a build called Build ...
- 【Java面试题】46 描述一下JVM加载class文件的原理机制?
JVM中类的装载是由类加载器(ClassLoader)和它的子类来实现的,Java中的类加载器是一个重要的Java运行时系统组件,它负责在运行时查找和装入类文件中的类. 由于Java的跨平台性,经过 ...
- js中页面跳转(href)中文参数传输方式
编码: escape(参数); 解码: unescape(参数);
- SharePoint 2010用“localhost”方式访问网站,File not found问题处理方式
场景:本地服务器上,用“localhost”方式访问网站:在某网站集(Site Collection)下的子网站(Sub Site)中,点击网站权限菜单(Site permissions)等关于调用L ...