大佬博客学习来自: https://blog.csdn.net/qq_40791842/article/details/99761346

大佬博客说这题涉及换根dp?我怎么没看出哪有换根dp思想?

枚举去边,那么就变成了两颗树,这条边提供的贡献,就是这两颗树中的路径。很妙,可是怎么求去掉这条边后的两颗子树的直径呢?

这个就很麻烦。于是我采用看代码学习。花了4个小时才从看懂加模仿打代码AC,说明我树形dp方面还是不足

贴题解图:

代码:

dp维护直径和最长链

//dp1[1][i]:除去节点i为子树的以fa[i]为终点的最长链
//dp1[0][i]:以节点i为子树的且以i为终点的最长链

//dp2[1][i]:除去节点i为子树的树直径
//dp2[0][i]:以节点i为子树的树直径

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define per(i,a,b) for(int i=a;i>=(b);--i)
#define pb push_back
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int N=1e5+10;
int n;
int mx[N*4];
vector<int>G[N];
int dp1[2][N],dp2[2][N];
void up(int id,int l,int r,int ql,int qr,int val)
{if(ql<=l&&r<=qr){mx[id]=max(mx[id],val);return ;}int mid=l+r>>1;if(ql<=mid) up(id<<1,l,mid,ql,qr,val);if(qr>mid) up(id<<1|1,mid+1,r,ql,qr,val);
}
void pushdown(int id)
{mx[id<<1]=max(mx[id<<1],mx[id]);mx[id<<1|1]=max(mx[id<<1|1],mx[id]);
}
int qu(int id,int l,int r,int pos)
{if(l==r) return mx[id];int mid=l+r>>1;if(mx[id]) pushdown(id);if(pos<=mid) return qu(id<<1,l,mid,pos);return qu(id<<1|1,mid+1,r,pos);
}
void getmax(int &fi,int &se,int val)//新添val更新最大、次大值
{if(val>=fi)se=fi,fi=val;else if(val>se) se=val;
}
void getmax(int &fi,int &se,int &th,int val)
{if(val>=fi){th=se,se=fi,fi=val;}else if(val>=se){th=se,se=val;}else if(val>th){th=val;}
}
void dfs1(int u,int fa)
{dp1[0][u]=dp2[0][u]=1;int fi=0,se=0;for(int v:G[u]){if(v==fa) continue;dfs1(v,u);dp1[0][u]=max(dp1[0][u],dp1[0][v]+1);//子树最长链的更新dp2[0][u]=max(dp2[0][u],dp2[0][v]);//子树的最大直径getmax(fi,se,dp1[0][v]);}dp2[0][u]=max(dp2[0][u],fi+se+1);//子树的最长链和次长链加本身
}
int newmax(int fi,int se,int val)
{if(fi==val) return se;return fi;
}
int newmax(int fi,int se,int th,int val)
{if(val==fi) return se+th;if(val==se) return fi+th;return fi+se;
}
void dfs2(int u,int fa)
{int sonlen=dp2[0][u],falen=dp2[1][u];if(sonlen&&falen){up(1,1,n,1,sonlen,falen);up(1,1,n,1,falen,sonlen);}///更新dp1[1]//最长链只需要更新子树的最长即可int fi=dp1[1][u],se=0,th=0;for(int v:G[u]){if(v==fa) continue;getmax(fi,se,th,dp1[0][v]);}for(int v:G[u]){if(v==fa) continue;dp1[1][v]=newmax(fi,se,dp1[0][v])+1;dp2[1][v]=newmax(fi,se,th,dp1[0][v])+1;}///dp2[1]先保存最长链组成的直径///更新dp2[1]fi=dp2[1][u],se=0;for(int v:G[u]){if(v==fa) continue;getmax(fi,se,dp2[0][v]);}///然后更新由子树的最大直径更新for(int v:G[u]){if(v==fa) continue;int tmp=newmax(fi,se,dp2[0][v]);dp2[1][v]=max(dp2[1][v],tmp);}for(int v:G[u]) if(v!=fa) dfs2(v,u);
}
int main()
{int _;cin>>_;while(_--){scanf("%d",&n);memset(mx,0,sizeof(mx));for(int i=1;i<n;++i){int u,v;scanf("%d%d",&u,&v);G[u].pb(v);G[v].pb(u);}dfs1(1,-1);dfs2(1,-1);ll ans=0;for(int i=1;i<=n;++i) ans+=qu(1,1,n,i);printf("%lld\n",ans);rep(i,1,n) G[i].clear();}
}

2019 杭电第九场1007 Rikka with Travels相关推荐

  1. 2019 Multi-University Training Contest 9 1007 Rikka with Travels

    HDU 6686 Rikka with Travels 题意: 在一颗树上选择两条不相交的路径的可能性有多少,路径长度定义为路径的顶点数. 题解: 初步思考,观察样例可以发现,求的是两条路径的有序对, ...

  2. 2019多校第九场 HDU6681 Rikka with Cake(欧拉图论定理,线段树)

    链接:HDU6681 Rikka with Cake 题意: 给出一个笛卡尔坐标系中左下角坐标为(0,0)(0,0)(0,0),右上角坐标为(n,m)(n,m)(n,m)的矩形,有K  (≤105)K ...

  3. 2022暑期杭电第九场

    文章目录 1003题 Fast Bubble Sort 题目大意 思路 代码 1007题 Matryoshka Doll--线性DP 题目大意 思路 代码 1008题 Shortest Path in ...

  4. 2019杭电多校第9场1002 Rikka with Cake HDU6681

    2019杭电多校第9场1002 Rikka with Cake HDU6681 题意:给你若干个点按上下左右切割平面,最后问平面内有几块被切割开来. 解法1:红黑树+思维+贪心 A:根据欧拉定理可以得 ...

  5. 2019杭电多校 第七场 Kejin Player 6656(求期望值)

    2019杭电多校 第七场 Kejin Player 6656(求期望值) 题目 http://acm.hdu.edu.cn/showproblem.php?pid=6656 题意 给你n,q.表示有n ...

  6. 【2019杭电多校训练赛】HDU6681 / 1002-Rikka with Cake 题解(扫描线)

    [2019杭电多校训练赛]HDU6681 / 1002-Rikka with Cake 题解 题意 思路 代码 题目来自于:HDU6681 Rikka with Cake 题意 题目的大意是给定你一个 ...

  7. 暑假N天乐【比赛篇】 —— 2019杭电暑期多校训练营(第一场)

    杭电多校第一场属实恐怖,我连补题的冲动都莫得了. 本来还想说按去年的经验来说,杭电是要比牛客稍微友好那么一丢丢的吧.结果当场打脸,签到题来了个最短路*2+网络流,这谁顶得住啊. 所以这两天都没在补这场 ...

  8. 19杭电计算机考研科目,2019杭电计算机考研初试科目、参考书目、报录比汇总

    本文将由新祥旭徐老师全方位的对杭电计算机.软件工程专业考研进行解析,主要有以下几个板块:学院介绍,专业情况介绍,2019录取情况分析,考研科目介绍,专业课参考书目及备考指导等几大方面. 一.学院介绍 ...

  9. 2019杭电计算机考研经验贴(初试+复试)

    为期一年的杭电考研之旅结束啦!一年的付出总算没有白费,顺利上岸,进入杭电脑机交互实验室.今天和导师签了双选表,现在在回学校的高铁上,想着写一份经验贴,为下一届考研的学弟学妹们留下点东西. 一.初试 杭 ...

最新文章

  1. ONES 万事联合创始人 amp; CTO 冯斌:企业服务产品的探索实践
  2. 为您的Office文档加把锁-ADRMS的安装
  3. mysql使用过程中的几个细节注意点
  4. CloudFoundry应用的自定义端口的命令行设置方式
  5. python里面的tuple与list对比
  6. PyQt 5信号与槽的几种高级玩法
  7. pandas基本操作
  8. 数字证书如何写入到ukey_ukey身份认证步骤
  9. java网络编程实现聊天小程序
  10. 服务器PHPWAMP_IN2安装redis
  11. (二)GNSS定位中的卫星轨道位置计算
  12. 用PowerPoint(PPT)快速制作炫酷数字倒计时
  13. ThreeJs中给立方体设置没有对角线的border
  14. 亚马逊账号关联怎么办?多账号如何自查?
  15. 鸿蒙系统跑分,麒麟9000+8GB内存 首发鸿蒙系统华为MatePad Pro2跑分首次曝光
  16. RSD处理高分5号高光谱(GF5 AHSI)数据(一)——正射校正和大气校正
  17. 手写JDBC的几个步骤(针对MySQL8.0以上的mysql数据库)
  18. React控制台警告Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until
  19. 日语初级语法复习整合 Day 11 - Day 15 Summary
  20. Camera,音频录制与Vitamio框架

热门文章

  1. 幼儿园买玩具_二进制枚举
  2. C语言中几种输入方式
  3. 苹果9是5g手机吗_苹果手机可以量体温?这是真的吗
  4. QT子窗体直接调用父窗体成员、函数、控件的方法
  5. 有哪些支持C4D的渲染农场
  6. BIM技术都是如何应用于水利工程中
  7. 苹果xr十大隐藏功能_别再说苹果“悬浮球”功能不好用,隐藏的实用小技巧,每天用得上...
  8. 2021届工科生求职日记1——Abing
  9. java-从菜鸟到大神
  10. unicode 生僻字_[微软拼音小技巧] 如何用Unicode输入生僻字