bzoj1912 树形dp求直径(新写法),求直径的两端点
通过回溯法可以求出直径的两个端点,同时注意有负权边的树求直径不可以用两次dfs来求,而必须用dp做
/*
分情况讨论问题
一条边也不加的情况,显然每条边要扫描两次,
该情况的答案是2(n-1)
只加一条边的情况,找到直径,将其变成一个环,在这个环上的所有边只要扫描一次,剩下的边就要扫描两次
设直径为L,该情况下的答案是 2(n-1-L)+L+1=2n-L-1=2(n-1)-(L-1)
加两条边的情况,在加入第一条边出现环的情况下,再加入一条边形成的环会和原来的环有重合
重合的部分任然要扫描两次,所以新加入的边要使形成的环和原来的环非重合的边和重合的边的差最大
那么如何快速求新加入的边?只要将第一条边加入后形成的环的边权值变成-1,然后再求一次直径即可
设第一次的直径L1,第二次的直径L2,那么该情况下的答案是2(n-1)-(L1-1)-(L2-1)
*/
#include<bits/stdc++.h>
using namespace std;
#define maxn 100005
struct Edge{int to,nxt,w;}edge[maxn<<];
int head[maxn],tot,n,k,ans;
void init(){
memset(head,-,sizeof head);
tot=;
}
void addedge(int u,int v){
edge[tot].w=;edge[tot].to=v;edge[tot].nxt=head[u];head[u]=tot++;
} int pre1[maxn],pre2[maxn],dp[maxn],mx;//记录x的最长和次长子链的边的下标
int dfs(int x,int fa)
{
int mx1=,mx2=;
for(int i=head[x];i!=-;i=edge[i].nxt)
if(edge[i].to!=fa)
{
int v=edge[i].w+dfs(edge[i].to,x);
if(v>mx1)mx2=mx1,mx1=v,pre2[x]=pre1[x],pre1[x]=i;
else if(v>mx2)mx2=v,pre2[x]=i;
}
if(mx1+mx2>ans)ans=mx1+mx2,mx=x;
return mx1;
} int main(){
init();
memset(pre1,-,sizeof pre1);
memset(pre2,-,sizeof pre2);
cin>>n>>k;
int tot=*n-;
for(int i=;i<n;i++){
int u,v;cin>>u>>v;
addedge(u,v);addedge(v,u);
}
dfs(,);
tot=tot-ans+;
if(k==)
{
ans=;
for(int i=pre1[mx];i!=-;i=pre1[edge[i].to])edge[i].w=edge[i^].w=-;
for(int i=pre2[mx];i!=-;i=pre1[edge[i].to])edge[i].w=edge[i^].w=-;
dfs(,);tot=tot-ans+;
}
cout<<tot<<endl;
}
bzoj1912 树形dp求直径(新写法),求直径的两端点的更多相关文章
- hdu 2196(方法1:经典树形DP+方法2:树的直径)
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- 【bzoj2500】幸福的道路 树形dp+倍增RMQ+二分
原文地址:http://www.cnblogs.com/GXZlegend/p/6825389.html 题目描述 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一 ...
- BZOJ 4890: [Tjoi2017]城市 树形dp
标签:树形dp,枚举,树的直径 一上来看到这个题就慌了,只想到了 $O(n^3)$ 的做法. 碰到这种题时要一步一步冷静地去分析,观察数据范围. 首先,$n\leqslant 5000$,所以可以先 ...
- 美团2017年CodeM大赛-初赛B轮 黑白树 (树形dp)
大意: 给定树, 初始每个点全为白色, 点$i$有权值$k_i$, 表示选择$i$后, 所有距离$i$小于$k_i$的祖先(包括i)会变为黑色, 求最少选多少个点能使所有点变为黑色. 链上情况的话, ...
- BZOJ 3572: [Hnoi2014]世界树 虚树 树形dp
https://www.lydsy.com/JudgeOnline/problem.php?id=3572 http://hzwer.com/6804.html 写的时候参考了hzwer的代码,不会写 ...
- HDU 4514 - 湫湫系列故事——设计风景线 - [并查集判无向图环][树形DP求树的直径]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4514 Time Limit: 6000/3000 MS (Java/Others) Memory Li ...
- 浅谈关于树形dp求树的直径问题
在一个有n个节点,n-1条无向边的无向图中,求图中最远两个节点的距离,那么将这个图看做一棵无根树,要求的即是树的直径. 求树的直径主要有两种方法:树形dp和两次bfs/dfs,因为我太菜了不会写后者这 ...
- 树形dp换根,求切断任意边形成的两个子树的直径——hdu6686
换根dp就是先任取一点为根,预处理出一些信息,然后在第二次dfs过程中进行状态的转移处理 本题难点在于任意割断一条边,求出剩下两棵子树的直径: 设割断的边为(u,v),设down[v]为以v为根的子树 ...
- 树形dp - 求树的直径
随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好. 现在已经勘探确定了n个位置可 ...
随机推荐
- webstorm更改scss输出路径
--no-cache --update $FileName$:$FileParentDir$\css\$FileNameWithoutExtension$.css $FileNameWithoutEx ...
- 【转载】java abstract class和interface的区别
转载:https://blog.csdn.net/b271737818/article/details/3950245 在Java语言中,abstract class和interface是支持抽象类定 ...
- 关于tcp queue
半连接队列:服务端维护的与客户端保持SYN_RECV状态的连接队列,等待客户端回复,当收到客户端ack后,如果条件允许(全连接队列未达到最大值),服务端进入ESTAB状态,从半连接队列移到全连接队列的 ...
- python(三)@staticmethod和@classmethod使用和区别
转载自[1] 一般要用某个类的方法,先要实例这个类. 但是可以通过@staticmethod和@classmethod,直接用“类.方法()”来调用这个方法. 而 @staticmethod和@cla ...
- Deep Neural Networks for Object Detection(翻译)
0 - Abstract 深度神经网络(DNNs)最近在图像分类任务上表现出了突出的性能.在这篇文章中,我们进一步深入探究使用DNNs进行目标检测的问题,这个问题不仅需要对物体进行分类,并且还需要对各 ...
- Javascript - ExtJs - ToolTip组件
一个浮动的提示信息组件…… Ext, //可选 指定箭头的位置 anchor: 'buttom', ...
- Eclipse下egit插件的使用
接触GIT已经很久了,但碰到的公司一直都在使用SVN,并因为各种理由拒绝换成GIT.今年换了份工作,乘着搭建公司新框架和项目的机会,总算在正式项目上使用了GIT.GIT的服务器直接就用了https:/ ...
- SPI总线协议及SPI时序图详解【转】
转自:https://www.cnblogs.com/adylee/p/5399742.html SPI,是英语Serial Peripheral Interface的缩写,顾名思义就是串行外围设备接 ...
- nginx proxy_set_header设置、自定义header
先来看下proxy_set_header的语法 语法: proxy_set_header field value; 默认值: proxy_set_header Host $proxy_host; pr ...
- CORS(Cross-origin resource sharing) “跨域资源共享”
CORS与JSONP的比较 在出现CORS标准之前, 我们还只能通过jsonp的形式去向“跨源”服务器去发送 XMLHttpRequest 请求,这种方式吃力不讨好,在请求方与接收方都需要做处理,而且 ...