联盟

题目描述

\(\text{G}\) 国周边的 \(n\) 个小国家构成一个联盟以抵御 \(\text{G}\) 国入侵, 为互相支援,他们建立了\(n−1\) 条双向通路, 使得任意两个国家可以经过通路相互到达.

当一个国家受到攻击时, 所有其它国家都会沿着最短路径前往这个国家进行支援,经过每条通路所需的时间均为\(1\). 定义一个国家的危险程度为所有国家全部赶到需要的最短时间, 联盟的危险程度为所有国家的危险程度的最大值.

为了降低危险程度, 联盟决定断开一条通路并任意连接一条通路, 使得危险程度尽可能小, 并要求改建完成之后任意两个国家可以经过通路互相到达.

他们决定让你来设计方案, 你需要告知在最优方案中可能断开哪些边,并给出任意一组最优方案.

输入输出格式

输入格式

第一行一个正整数\(n\).

接下来 \(n-1\) 行每行两个正整数, 表示一条\(u_i\), \(v_i\) 之间的边.

输出格式

输出第一行一个整数表示最小危险程度.

第二行一个整数 \(k\), 表示可能被断开的边的数量, 接下来 \(k\) 个数, 表示

可能断开的边的编号, 按升序输出.

接下来一行四个正整数表示一组最优方案, 分别表示断开和新建的边的端点, 只需给出任意一组合法的方案即可.

提示

对于\(20\%\)的数据,\(n\le 30\).

对于\(40\%\)的数据,\(n\le 300\).

对于\(60\%\)的数据,\(n\le 3000\).

对于\(100\%\)的数据,\(n\le 300000\).

如果你的答案仅第一行正确, 你可以获得 \(25\%\) 的分数,

如果你的答案仅前两行正确, 你可以获得 \(50\%\) 的分数,

为保证得到部分分请确保提交程序的输出格式符合题目要求.


其实思维没什么难度。

枚举断边,处理出两颗分开的树的直径,求一下新的直径就可以了

已知两棵树的直径分别为\(a,b\),用一条边连接这两颗树得到的最小直径是\(max(a,b,\lceil \frac{a}{2} \rceil +\lceil \frac{b}{2} \rceil +1)\),就是连接这个直径中间的点

细节非常多,写起来很恶心,可以练练代码能力

考场上硬是没调出来爆0了。。。


Code:

#include <cstdio>
#include <algorithm>
#include <vector>
const int N=3e5+10;
int Next[N<<1],to[N<<1],head[N],cnt;
int max(int x,int y){return x>y?x:y;}
void add(int u,int v,int eid)
{
to[++cnt]=v,Next[cnt]=head[u],head[u]=cnt;
}
int n,dis[N],dp[N],s[N],tot0,ans=0x7fffffff;
void dfs1(int now,int fa)
{
int mx1=0,mx2=0,child=0;
for(int i=head[now];i;i=Next[i])
{
int v=to[i];
if(v==fa) continue;
child++;
dfs1(v,now);
dp[now]=max(dp[v],dp[now]);
dis[now]=max(dis[now],dis[v]+1);
if(mx1<=dis[v]) mx2=mx1,mx1=dis[v];
else if(mx2<dis[v]) mx2=dis[v];
}
if(child>1) dp[now]=max(dp[now],mx1+mx2+2);
else dp[now]=max(dp[now],mx1+mx2+child);
}
void dfs2(int now,int fa,int len1,int len2,int num)
{
int mi=max(max(dp[now],len1),(dp[now]+1)/2+(len1+1)/2+1),child=0;
if(mi<ans) tot0=0,s[++tot0]=num,ans=mi;
else if(mi==ans) s[++tot0]=num;
int max1=0,dmax1=0,fmax1=0,max2=0,dmax2=0;
for(int i=head[now];i;i=Next[i])
{
int v=to[i];
if(v==fa) continue;
if(dis[v]>=max1) fmax1=dmax1,dmax1=max1,max1=dis[v];
else if(dis[v]>=dmax1) fmax1=dmax1,dmax1=dis[v];
else if(dis[v]>fmax1) fmax1=dis[v];
if(dp[v]>=max2) dmax2=max2,max2=dp[v];
else if(dp[v]>dmax2) dmax2=dp[v];
++child;
}
for(int i=head[now];i;i=Next[i])
{
int v=to[i];
if(v==fa) continue;
int mxx0,mxx1;
if(max1==dis[v]) mxx0=dmax1,mxx1=fmax1;
else if(dmax1==dis[v]) mxx0=max1,mxx1=fmax1;
else mxx0=max1,mxx1=dmax1;//儿子链的最大值
int mxx2=(max2==dp[v]?dmax2:max2);//其他儿子的直径
int lenp=max((len2+(mxx0+1)*(child>1)),(mxx0+mxx1+2)*(child>2));//三条链的最值
int le1=max(len1,max(mxx2,lenp)),le2=max(len2+1,(mxx0+2)*(child>1));
dfs2(v,now,le1,le2,i+1>>1);
}
}
struct edge
{
int u,v;
}e[N];
int s0[2][N],mxlen,ll,rr,pre[N];
void dfs3(int now,int fa,int len)
{
if(len>mxlen) mxlen=len,ll=now;
for(int i=head[now];i;i=Next[i])
{
int v=to[i];
if(v==fa||(i+1>>1)==s[1]) continue;
dfs3(v,now,len+1);
}
}
void dfs4(int now,int fa,int len)
{
if(len>mxlen) mxlen=len,rr=now;
for(int i=head[now];i;i=Next[i])
{
int v=to[i];
if(v==fa||(i+1>>1)==s[1]) continue;
pre[v]=now;
dfs4(v,now,len+1);
}
}
void getd(int st,int ty)
{
mxlen=0;
dfs3(st,0,1);
mxlen=0;
dfs4(ll,0,1);
int now=rr;
while(now) s0[ty][++s0[ty][0]]=now,now=pre[now];
}
void work3()
{
int lu=e[s[1]].u,lv=e[s[1]].v;
getd(lu,0),getd(lv,1);
int u=s0[0][s0[0][0]+1>>1],v=s0[1][s0[1][0]+1>>1];
printf("%d %d %d %d\n",lu,lv,u,v);
}
int main()
{
scanf("%d",&n);
for(int u,v,i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
e[i]={u,v};
add(u,v,i),add(v,u,i);
}
dfs1(1,0);
dfs2(1,0,0,0,0);
printf("%d\n",ans);
std::sort(s+1,s+1+tot0);
printf("%d ",tot0);
for(int i=1;i<=tot0;i++) printf("%d ",s[i]);
printf("\n");
work3();
return 0;
}

2018.10.2

雅礼集训 Day2 T3 联盟 解题报告的更多相关文章

  1. 雅礼集训 Day3 T3 w 解题报告

    w 题目背景 \(\frac 14\)遇到了一道水题,双完全不会做,于是去请教小\(\text{D}\).小\(\text{D}\)看了\(0.607^2\)眼就切掉了这题,嘲讽了\(\frac 14 ...

  2. 雅礼集训 Day1 T3 画作 解题报告

    画作 题目描述 小\(\mathrm{G}\)的喜欢作画,尤其喜欢仅使用黑白两色作画. 画作可以抽象成一个\(r\times c\)大小的\(01\)矩阵.现在小\(\mathrm{G}\)构思好了他 ...

  3. 雅礼集训 Day5 T3 题 解题报告

    题 题目背景 由于出题人赶时间所以没办法编故事来作为背景. 题目描述 一开始有\(n\)个苹果,\(m\)个人依次来吃苹果,第\(i\)个人会尝试吃\(u_i\)或\(v_i\)号苹果,具体来说分三种 ...

  4. 「雅礼集训 2017 Day1」 解题报告

    「雅礼集训 2017 Day1」市场 挺神仙的一题.涉及区间加.区间除.区间最小值和区间和.虽然标算就是暴力,但是复杂度是有保证的. 我们知道如果线段树上的一个结点,\(max=min\) 或者 \( ...

  5. 雅礼集训 Day7 T1 Equation 解题报告

    Reverse 题目背景 小\(\text{G}\)有一个长度为\(n\)的\(01\)串\(T\),其中只有\(T_S=1\),其余位置都是\(0\).现在小\(\text{G}\)可以进行若干次以 ...

  6. 雅礼集训 Day6 T2 Equation 解题报告

    Equation 题目描述 有一棵\(n\)个点的以\(1\)为根的树,以及\(n\)个整数变量\(x_i\).树上\(i\)的父亲是\(f_i\),每条边\((i,f_i)\)有一个权值\(w_i\ ...

  7. 雅礼集训 Day6 T1 Merchant 解题报告

    Merchant 题目描述 有\(n\)个物品,第\(i\)个物品有两个属性\(k_i,b_i\),表示它在时刻\(x\)的价值为\(k_i\times x+b_i\). 当前处于时刻\(0\),你可 ...

  8. 雅礼集训 Day3 T2 u 解题报告

    u 题目背景 \(\frac 14\) 遇到了一道水题,完全不会做,于是去请教小\(\text{D}\).小\(\text{D}\)看了一眼就切掉了这题,嘲讽了\(\frac 14\)一番就离开了. ...

  9. 雅礼集训 Day3 T2 v 解题报告

    v 题目背景 \(\frac 14\)遇到了一道水题,又完全不会做,于是去请教小\(\text{D}\).小\(\text{D}\)看了\(0.607\)眼就切掉了这题,嘲讽了\(\frac 14\) ...

随机推荐

  1. centos7部署harbor

    官网 https://github.com/goharbor/harbor 1.升级系统内核 rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrep ...

  2. FastDFS文件管理系统

    一.FastDFS介绍 FastDFS 是一个开源的高性能分布式文件系统(DFS). 它的主要功能包括:文件存储,文件同步和文件访问,以及高容量和负载平衡.主要解决了海量数据存储问题,特别适合以中小文 ...

  3. zip压缩工具,unzip解压缩工具

    zip压缩工具,unzip解压缩工具=================== [root@aminglinux tmp]# yum install -y zip[root@aminglinux tmp] ...

  4. 大数据学习(一) | 初识 Hadoop

    作者: seriouszyx 首发地址:https://seriouszyx.top/ 代码均可在 Github 上找到(求Star) 最近想要了解一些前沿技术,不能一门心思眼中只有 web,因为我目 ...

  5. Windows Server 2012 搭建DHCP及远程路由访问

    1.1    基础环境信息 1.2    DHCP与远程访问服务器角色安装 1.服务器管理器—>仪表板—>添加角色和功能,出现添加角色和功能向导,点击下一步 2.选择安装类型为基于角色或基 ...

  6. PHP成随机字符串

    生成随机字符串 /** * 随机字符串 * @param int $len * @return string */ function randomStr($len = 32) { $chars = & ...

  7. Gson转Map时,Int会变成double解决方法

    package com.cdy.demo; import java.lang.reflect.Type; import java.util.HashMap; import java.util.Map; ...

  8. 数据结构学习-AVL平衡树

    环境:C++ 11 + win10 IDE:Clion 2018.3 AVL平衡树是在BST二叉查找树的基础上添加了平衡机制. 我们把平衡的BST认为是任一节点的左子树和右子树的高度差为-1,0,1中 ...

  9. 24-webhost的配置

    1-新建asp.net core空项目 2-创建setting.json文件 3- 配制Progrom类中CreateWebHostBuilder 4-获取配置的文件 5-显示结果

  10. Spark 源码阅读——任务提交过程

    当我们在使用spark编写mr作业是,最后都要涉及到调用reduce,foreach或者是count这类action来触发作业的提交,所以,当我们查看这些方法的源码时,发现底层都调用了SparkCon ...