两遍树形DP求出每个点开始往上往下走的前3长路以及每个点上下部分的直径。

枚举每条边断开,设两边直径分别为$A,B$,则:

对于第一问,连接两边直径的中点可得直径为$\max(A,B,\lfloor\frac{A+1}{2}\rfloor+\lfloor\frac{B+1}{2}\rfloor+1)$的新树。

对于第二问,连接两边直径的端点可得直径为$A+B+1$的新树。

时间复杂度$O(n)$。

#include<cstdio>
#define N 500010
int n,i,j,x,y,g[N],v[N<<1],nxt[N<<1],del[N<<1],ed,fa[N];
int d[N][3],f[N],w[N][2],u[N],h[N],ans1=N,ans2,ch1,ch2,id,dis[N],pre[N],q[N];
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
inline void add(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
inline void up(int&a,int b){if(a<b)a=b;}
inline int max(int a,int b){return a>b?a:b;}
void caldown(int x){
for(int i=g[x];i;i=nxt[i])if(v[i]!=fa[x]){
int y=v[i];
fa[v[i]]=x;
caldown(v[i]);
int t=d[y][0]+1;
if(t>d[x][0])d[x][2]=d[x][1],d[x][1]=d[x][0],d[x][0]=t;
else if(t>d[x][1])d[x][2]=d[x][1],d[x][1]=t;
else if(t>d[x][2])d[x][2]=t;
up(f[x],t=f[y]);
if(t>w[x][0])w[x][1]=w[x][0],w[x][0]=t;else if(t>w[x][1])w[x][1]=t;
}
up(f[x],d[x][0]+d[x][1]);
}
void calup(int x){
if(x!=1){
int y=fa[x];
u[x]=u[y];
up(u[x],d[y][0]==d[x][0]+1?d[y][1]:d[y][0]);
u[x]++;
h[x]=h[y];
up(h[x],w[y][0]==f[x]?w[y][1]:w[y][0]);
int a,b,c=u[y];
if(d[y][0]==d[x][0]+1)a=d[y][1],b=d[y][2];
else a=d[y][0],b=d[y][1]==d[x][0]+1?d[y][2]:d[y][1];
up(h[x],a+b),up(h[x],a+c),up(h[x],b+c);
int t=max(max(h[x],f[x]),(h[x]+1)/2+(f[x]+1)/2+1);
if(t<ans1)ans1=t,ch1=x;
t=h[x]+f[x]+1;
if(t>ans2)ans2=t,ch2=x;
up(h[x],a+1),up(h[x],b+1),up(h[x],c+1);
}
for(int i=g[x];i;i=nxt[i])if(v[i]!=fa[x])calup(v[i]);
}
void dfs(int x,int y){
pre[x]=y;
if(dis[x]>dis[id])id=x;
for(int i=g[x];i;i=nxt[i])if(v[i]!=y&&!del[i])dis[v[i]]=dis[x]+1,dfs(v[i],x);
}
int main(){
read(n);
for(i=1;i<n;i++)read(x),read(y),add(x,y),add(y,x);
caldown(1),calup(1);
printf("%d %d %d",ans1,ch1,fa[ch1]);
for(i=g[ch1];i;i=nxt[i])if(v[i]==fa[ch1])del[i]=1;
for(i=g[fa[ch1]];i;i=nxt[i])if(v[i]==ch1)del[i]=1;
dfs(id=ch1,dis[ch1]=0);
dfs(id,dis[id]=0);
for(i=1;id;i++,id=pre[id])q[i]=id;
printf(" %d",q[i>>1]);
dfs(id=fa[ch1],dis[fa[ch1]]=0);
dfs(id,dis[id]=0);
for(i=1;id;i++,id=pre[id])q[i]=id;
printf(" %d\n",q[i>>1]);
for(i=g[ch1];i;i=nxt[i])if(v[i]==fa[ch1])del[i]=0;
for(i=g[fa[ch1]];i;i=nxt[i])if(v[i]==ch1)del[i]=0;
printf("%d %d %d",ans2,ch2,fa[ch2]);
for(i=g[ch2];i;i=nxt[i])if(v[i]==fa[ch2])del[i]=1;
for(i=g[fa[ch2]];i;i=nxt[i])if(v[i]==ch2)del[i]=1;
dfs(id=ch2,dis[ch2]=0);
printf(" %d",id);
dfs(id=fa[ch2],dis[fa[ch2]]=0);
printf(" %d",id);
return 0;
}

  

BZOJ4379 : [POI2015]Modernizacja autostrady的更多相关文章

  1. [BZOJ4379][POI2015]Modernizacja autostrady[树的直径+换根dp]

    题意 给定一棵 \(n\) 个节点的树,可以断掉一条边再连接任意两个点,询问新构成的树的直径的最小和最大值. \(n\leq 5\times 10^5\) . 分析 记断掉一条边之后两棵树的直径为 \ ...

  2. 【BZOJ4379】[POI2015]Modernizacja autostrady 树形DP

    [BZOJ4379][POI2015]Modernizacja autostrady Description 给定一棵无根树,边权都是1,请去掉一条边并加上一条新边,定义直径为最远的两个点的距离,请输 ...

  3. @bzoj - 4379@ [POI2015] Modernizacja autostrady

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一棵无根树,边权都是1,请去掉一条边并加上一条新边,定义直径 ...

  4. POI2015题解

    POI2015题解 吐槽一下为什么POI2015开始就成了破烂波兰文题目名了啊... 咕了一道3748没写打表题没什么意思,还剩\(BZOJ\)上的\(14\)道题. [BZOJ3746][POI20 ...

  5. [Poi2015]

    [POI2015]Łasuchy 一看以为是sb题 简单来说就是每个人获得热量要尽量多 不能找别人 首先这道题好像我自己找不到NIE的情况 很容易想到一个优化 如果一个数/2>另一个数 那么一定 ...

  6. Work at DP

    转载请注明出处:http://www.cnblogs.com/TSHugh/p/8858805.html Prepared: (无notes的波兰题目的notes见我的波兰题目补全计划)BZOJ #3 ...

  7. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  8. poi2015 bzoj4377-4386训练

    就按时间顺序写吧 完成度:10/10 3.30 bzoj4385 首先一定是删去连续d个数,然后枚举终点,起点显然有单调性,用单调队列乱搞搞就可以啦 bzoj4378 首先才结论:可行当且仅当把所有大 ...

  9. BZOJ 4385: [POI2015]Wilcze doły

    4385: [POI2015]Wilcze doły Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 648  Solved: 263[Submit][ ...

随机推荐

  1. 体系结构设计MVC

    体系结构设计MVC(viso图)GIT: https://coding.net/u/lklzjh/p/travel/git/blob/master/%E4%BD%93%E7%B3%BB%E7%BB%9 ...

  2. MyBatis魔法堂:即学即用篇

    一.前言                   本篇内容以理解MyBatis的基本用法和快速在项目中实践为目的,遵循Make it work,better and excellent原则. 技术栈为My ...

  3. JavaWeb学习之JSTL自定义标签库的使用、JSTL自定义函数库(7)

    一.自定义标签,步骤 * 确定需求 * <my:date /> 输出当前系统的时间 yyyy-MM-dd hh:mm:ss:SSS * 编写Java类 新建包名:com.yxl.tag,新 ...

  4. MVC基础知识

    1.View中获取Control和View: //获取控制器名称: ViewContext.RouteData.Values["controller"].ToString(); / ...

  5. SQLAlchemy Core插入数据,有好几种方法呢

    看是一次插入一条还是多条, 看是数据表名是变量还是常量, 操作还是很灵活的, 主要看哪种顺手顺眼啦. #coding=utf-8 from datetime import datetime from ...

  6. Win7下的内置FTP组件的设置详解

    在局域网中共享文件,FTP是比较方便的方案之一.Win7内部集成了FTP,只是设置起来颇费一番功夫.着文以记之. 一.安装FTP组件 由于Win7默认没有安装FTP组件.故FTP的设置第一步就是安装F ...

  7. Effective C++ 之 Item 3:尽可能使用 const

    Effective C++ Chapter 1. 让自己习惯C++(Accustoming Yourself to C++) Item 3. 尽可能使用 const (Use const whenev ...

  8. BZOJ 3289: Mato的文件管理 莫队+BIT

    3289: Mato的文件管理 Description Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份有一个大小和一个编号.为了防止他人偷拷,这些资料都是加密过的 ...

  9. I/O复用模型之select学习

    linux下的I/O模型可以分为5种: 1.阻塞式I/O模型 2.非阻塞式I/O模型 3.I/O复用模型 4.信号驱动I/O模型 5.异步I/O模型 简单解释: 阻塞和非阻塞:就是说需要做一件事的时候 ...

  10. RDS MySQL 全文检索相关问题的处理

    RDS MySQL 全文检索相关问题 1. RDS MySQL 对全文检索的支持 2. RDS MySQL 全文检索相关参数 3. RDS MySQL 全文检索中文支持 3.1 MyISAM 引擎表 ...