两遍树形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. Android 添加cookie

    /** * 添加cookie * * @param url */ private void setCookie(String url) { // 获取uid String uid = UserData ...

  2. MVC – 4.mvc初体验(2)

    5.显示学员列表 效果 数据表 5.1 首先,在文件夹Models新建一个新建项(W),选择ADO.NET 实体数据模型 (SingleTest.edmx) 5.2 建一个控制器,StudentsCo ...

  3. JavaWeb学习之转发和重定向、会话技术:cookie、session、验证码实例、URLConnection使用(下载网页)(4)

    1.转发和重定向 HttpServletResponse response 转发: RequestDispatcher dispatcher = request.getRequestDispatche ...

  4. 在多台服务器上简单实现Redis的数据主从复制(3)(转载)

    转载地址:http://www.cnblogs.com/liping13599168/archive/2011/04/14/2016226.html Redis的主从复制功能非常强大,一个master ...

  5. 攻城狮在路上(壹) Hibernate(十三)--- Hibernate的检索方式(上)

    Hibernate提供了以下几种检索对象的方式: A.导航对象图检索方式. B.OID检索方式.Session.get() load(); C.HQL检索方式.Query. D.QBC检索方式.Que ...

  6. 时间:UTC时间、GMT时间、本地时间、Unix时间戳

    转自:http://blog.csdn.net/u012102306/article/details/51538574 1.UTC时间 与 GMT时间 我们可以认为格林威治时间就是时间协调时间(GMT ...

  7. VS2010下配置OpenMesh

    从www.openmesh.org下载最新版的安装包或者源代码,注意下载与自己系统匹配的版本,我下的是VS2010预编译版的,下载源码自己编译是一样的.安装好Visual Studio. 安装Open ...

  8. Ring3无敌进程让你的进程变得和smss.exe一样支持64

    本帖最后由 奋斗丶小Z 于 2016-6-6 13:39 编辑 此函数可以启用或关闭开启之后变得和系统进程一样被杀系统直接蓝屏系统进程也是此函数实现的上图 可以用于进程保护 <ignore_js ...

  9. html table之 全选,全不选

    就是这个小功能让我和组长引发争端,就是这个小功能让我差点"被"辞职,就是这个自封装的js方法让我放下了对组长的敬畏之心,现在分享一下,其实也很简单,但是真的有这么简单吗? < ...

  10. 让Web API支持$format参数的方法

    public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web AP ...