hdu 4679 (树形DP)
题意:给一棵树,边的权值都是1,摧毁每条边是有代价的,选择摧毁一条边,把一棵树分成两部分,求出两部分中距离最大的两点的距离,求出距离*代价最小的边,多条的话输出序号最小的。
刚开始理解错题意了,wrong了几次,一直在纠结摧毁一条边后上边的树的最远距离怎么求,儿子树的最远距离就是所有子树的最长边+次长边就可以了。当我们求到一个节点u时,肯定有一个祖先节点,该祖先节点在摧毁与u链接的边后剩余的子树中最长的边和次长边之和是最大的,如果摧毁u与子节点的边时,就要考虑那个祖先节点的位置了,可能就是u这个节点。如果摧毁u与子节点的一条边后,可以求出u的子树中的最长边和次长边,如果次长边要是大于祖先节点的最长边,祖先节点就更新为u节点,如果u的子树的最长边+到祖先节点的距离大于祖先的次长边的话,祖先节点也更新为u,u的最长边和次长边要更新。
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#define N 100001
int n,head[N],num,vis[N],dp[N][3],dp1[N][2],min,iid;
struct edge
{
int st,ed,next,w,id;
}E[N*2];
void addedge(int x,int y,int w,int id)
{
E[num].st=x;E[num].ed=y; E[num].w=w;E[num].id=id;E[num].next=head[x];head[x]=num++;
}
int dfs(int u)
{
int i,v;
vis[u]=1;
for(i=head[u];i!=-1;i=E[i].next)
{
v=E[i].ed;
if(vis[v]==1)continue;
int temp=dfs(v)+1;
if(temp>dp[u][2])//所有子树的最长边
{
dp[u][0]=dp[u][1];
dp[u][1]=dp[u][2];
dp[u][2]=temp;
}
else if(temp>dp[u][1])//次长边
{
dp[u][0]=dp[u][1];
dp[u][1]=temp;
}
else if(temp>dp[u][0])//第三长边
dp[u][0]=temp;
}
return dp[u][2];
}
void dfs1(int u,int father,int dis)
{
vis[u]=1;
int i,v,ans,temp,flag;
int y1,y0;//摧毁一条边后当前节点u链接的所有子树的最长边和次长边
for(i=head[u];i!=-1;i=E[i].next)
{
dp1[u][1]=dp1[father][1];dp1[u][0]=dp1[father][0];//祖先节点的最长和次长边之和最大的
v=E[i].ed;
flag=dis;//当前节点到最长和次长边之和最大的祖先节点的距离
if(vis[v]==1)continue;
if(dp[v][2]+1==dp[u][2])//当前边在父节点u的最长边上
{y1=dp[u][1];y0=dp[u][0];}
else if(dp[v][2]+1==dp[u][1])//当前边在父节点u的次长边上
{y1=dp[u][2];y0=dp[u][0];}
else {y1=dp[u][2];y0=dp[u][1];}
if(y0>dp1[u][1])//如果子树的次长边比祖先节点的最长边大。就更新当前节点的最长边和次长边
{
dp1[u][1]=y1;
dp1[u][0]=y0;
flag=0;//祖先节点变成当前节点,
}
else if(y1+dis>dp1[u][0])//如果子树的最长边+到祖先节点的距离大于祖先的次长边
{
dp1[u][1]+=dis;//当前节点的最长边加上到祖先的距离
dp1[u][0]=y1;//次长边=子树的最长边
flag=0;
}
if(dp1[u][1]<dp1[u][0]){temp=dp1[u][1];dp1[u][1]=dp1[u][0];dp1[u][0]=temp;}
ans=dp1[u][1]+dp1[u][0];//摧毁当前边后,u所在树的最远两点距离
if(ans<dp[v][2]+dp[v][1])ans=dp[v][2]+dp[v][1];//与儿子v所在树的最远两点距离比较
if(ans*E[i].w<min){min=ans*E[i].w;iid=E[i].id;}//更新最小值
else if(ans*E[i].w==min&&iid>E[i].id){min=ans*E[i].w;iid=E[i].id;}
dfs1(v,u,flag+1);
}
}
int main()
{
int i,x,y,w,t,op=1;
scanf("%d",&t);
while(t--)
{
memset(head,-1,sizeof(head));
num=0;
scanf("%d",&n);
for(i=1;i<n;i++)
{
scanf("%d%d%d",&x,&y,&w);
addedge(x,y,w,i);
addedge(y,x,w,i);
}
min=1000000000;iid=1000000;
memset(dp,0,sizeof(dp));
memset(dp1,0,sizeof(dp1));
memset(vis,0,sizeof(vis));
dfs(1);
memset(vis,0,sizeof(vis));
dp1[0][1]=0;dp1[0][0]=0;
dfs1(1,0,0);
printf("Case #%d: ",op++);
printf("%d\n",iid);
}
return 0;
}
hdu 4679 (树形DP)的更多相关文章
- hdu 4123 树形DP+RMQ
http://acm.hdu.edu.cn/showproblem.php? pid=4123 Problem Description Bob wants to hold a race to enco ...
- 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 ...
- HDU 2196树形DP(2个方向)
HDU 2196 [题目链接]HDU 2196 [题目类型]树形DP(2个方向) &题意: 题意是求树中每个点到所有叶子节点的距离的最大值是多少. &题解: 2次dfs,先把子树的最大 ...
- HDU 1520 树形DP入门
HDU 1520 [题目链接]HDU 1520 [题目类型]树形DP &题意: 某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上司,现在已知 ...
- codevs 1380/HDU 1520 树形dp
1380 没有上司的舞会 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 回到问题 题目描述 Description Ural大学有N个职员 ...
- HDU 5834 [树形dp]
/* 题意:n个点组成的树,点和边都有权值,当第一次访问某个点的时候获得利益为点的权值 每次经过一条边,丢失利益为边的权值.问从第i个点出发,获得的利益最大是多少. 输入: 测试样例组数T n n个数 ...
- hdu 4267 树形DP
思路:先dfs一下,找出1,n间的路径长度和价值,回溯时将该路径长度和价值清零.那么对剩下的图就可以直接树形dp求解了. #include<iostream> #include<al ...
- hdu 4607 (树形DP)
当时比赛的时候我们找出来只要求出树的最长的边的节点数ans,如果要访问点的个数n小于ans距离直接就是n-1 如果大于的话就是(n-ans)*2+ans-1,当时求树的直径难倒我们了,都不会树形dp ...
随机推荐
- Java 网络编程(六) 使用无连接的数据报(UDP)进行通信
连接地址:http://www.cnblogs.com/mengdd/archive/2013/03/10/2952673.html 使用无连接的数据报(UDP)进行通信 什么是Datagram? 数 ...
- BZOJ 1191: [HNOI2006]超级英雄Hero(二分图匹配)
云神说他二分图匹配从来都是用网络流水过去的...我要发扬他的精神.. 这道题明显是二分图匹配.网络流的话可以二分答案+最大流.虽然跑得很慢.... -------------------------- ...
- Spring配置机制的优缺点 - Annotation vs XML
转自 http://tianzongqi.iteye.com/blog/1458002 XML配置的优缺点: 优点: XML配置方式进一步降低了耦合,使得应用更加容易扩展,即使对配置文件进一步修改也不 ...
- php如何开启GD库
GD库是干什么用的呢!它是php处理图形的扩展库,GD库提供了一系列用来处理图片的API,使用GD库可以处理图片,或者生成图片.GD库在php中默认是没有开启的,如果想让它支持图片处理功能,那么就要手 ...
- C#_socket拆包_封包_模拟乱序包
拆包一直是个硬伤呀,MLGB的,服务端各种乱数据,果断整理下 拆包思路:设计一个网络协议,一般都会分包,一个包就相当于一个逻辑上的命令. .如果我们用udp协议,省事的多,一次会收到一个完整的包,但U ...
- [LeetCode]题解(python):073-Set Matrix Zeroes
题目来源: https://leetcode.com/problems/set-matrix-zeroes/ 题意分析: 输入一个m×n矩阵,如果出现有0,那么将对应的行和列都变成0. 题目思路: 简 ...
- IOS 表视图(UITableVIew)的使用方法(5)表视图的编辑功能(删除)
默认的,如果表视图支持编辑,那用户可以通过两种方式来删除某些行,其一为单击左侧的红色按钮后行右侧显示“Delete”按钮,其二为在单元行上的手指向左滑动,“Delete”按钮也会出现供用户单击.无论哪 ...
- LintCode-丢失的第一个正整数
题目描述: 给出一个无序的正数数组,找出其中没有出现的最小正整数. 样例 如果给出 [1,2,0], return 3 如果给出 [3,4,-1,1], return 2 挑战 只允许时间复杂度O(n ...
- 国内BI工具/报表工具厂商简介
v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VM ...
- 转;说说AngularJS中的$parse和$eval
说说AngularJS中的$parse和$eval AngularJS的初学者常常会对$parse和$eval两个内建服务感到有些困惑,今天我们就来说说AngularJS中的$parse和$eval. ...