题目:http://codeforces.com/contest/1182/problem/D

很好的思路是从度数为1的点和直径来入手。

找一条直径。看看直径的两个端点是否合法。

如果都不合法,那么根一定在直径中点 md 伸出去的子树里。

伸出去的子树里的任意一点 x 到伸出去的子树里的一个叶子 y 的距离一定小于到直径端点的距离。不然直径就不是那条。

所以新的根只能是一个叶子,并且满足该叶子到其他所有叶子的距离一样。

也就是说,根一定是 md 伸出去的子树里最近的叶子。并且可以发现 md 到该叶子的路径上没有分叉,不然该叶子到另一个叶子的距离很近。

如果有多个满足该条件的叶子,任选一个判断是否可行即可。如果一个不可行,其他一定也不可行。

似乎没有开足够的栈?把 DFS 改成 BFS 才过掉。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return fx?ret:-ret;
}
const int N=1e5+;
int n,hd[N],xnt,to[N<<],nxt[N<<],rd[N];
int r0,r1,md,mx,mn,vl[N]; bool fx,flag;
int q[N],dis[N],fa[N],he,tl;
void add(int x,int y)
{to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;rd[y]++;}
void chk_dfs(int cr)
{
he=tl=; q[++tl]=cr; dis[cr]=; fa[cr]=;
while(he<tl)
{
int k=q[++he],d=dis[k];
if(vl[d]&&vl[d]!=rd[k]){flag=;return;}
vl[d]=rd[k];
for(int i=hd[k],v;i;i=nxt[i])
if((v=to[i])!=fa[k])
{
fa[v]=k; dis[v]=d+; q[++tl]=v;
}
}
}
bool chk(int x)
{
memset(vl,,sizeof vl); flag=;
chk_dfs(x); return flag;
}
void dfs(int cr)
{
he=tl=; q[++tl]=cr; dis[cr]=; fa[cr]=;
while(he<tl)
{
int k=q[++he],d=dis[k];
if(d>mx){mx=dis[k]; if(!fx)r0=k;else r1=k;}
for(int i=hd[k],v;i;i=nxt[i])
if((v=to[i])!=fa[k])
{
fa[v]=k; dis[v]=d+; q[++tl]=v;
}
}
}
void dfsx(int cr)
{
he=tl=; q[++tl]=cr; dis[cr]=; fa[cr]=;
while(he<tl)
{
int k=q[++he],d=dis[k];
if(k==r1)
{
int stp=;
while()
{
k=fa[k];stp++;
if(stp==mx){md=k;return;}
}
}
for(int i=hd[k],v;i;i=nxt[i])
if((v=to[i])!=fa[k])
{
fa[v]=k; dis[v]=d+; q[++tl]=v;
}
}
}
void dfs2(int cr)
{
he=tl=; q[++tl]=cr; dis[cr]=; fa[cr]=;
while(he<tl)
{
int k=q[++he],d=dis[k];
if(rd[k]!=&&k!=md)
{
if(rd[k]==&&dis[k]<mn)mn=dis[k],r0=k;
continue;
}
for(int i=hd[k],v;i;i=nxt[i])
if((v=to[i])!=fa[k])
{
fa[v]=k; dis[v]=d+; q[++tl]=v;
}
}
}
int main()
{
n=rdn();
for(int i=,u,v;i<n;i++)
u=rdn(),v=rdn(),add(u,v),add(v,u);
mx=-;dfs();
if(chk(r0)){printf("%d\n",r0);return ;}
mx=-;fx=; dfs(r0);
if(chk(r1)){printf("%d\n",r1);return ;}
if(mx<||(mx&)){puts("-1");return ;}//mx<0
mx>>=,dfsx(r0);
if(chk(md)){printf("%d\n",md);return ;}
mn=N; dfs2(md);
if(r0&&chk(r0))printf("%d\n",r0);
else puts("-1");
return ;
}

CF1182 D Complete Mirror——思路的更多相关文章

  1. Codeforces 1182D Complete Mirror [树哈希]

    Codeforces 中考考完之后第一个AC,纪念一下qwq 思路 简单理解一下题之后就可以发现其实就是要求一个点,使得把它提为根之后整棵树显得非常对称. 很容易想到树哈希来判结构是否相同,而且由于只 ...

  2. Codeforces 1182D Complete Mirror 树的重心乱搞 / 树的直径 / 拓扑排序

    题意:给你一颗树,问这颗树是否存在一个根,使得对于任意两点,如果它们到根的距离相同,那么它们的度必须相等. 思路1:树的重心乱搞 根据样例发现,树的重心可能是答案,所以我们可以先判断一下树的重心可不可 ...

  3. cf1182D Complete Mirror

    可以得到一个结论, 可行的点要么是直径端点, 要么是直径中点, 要么是直径中点引出的链中最短的端点 #include<cstdio> #include<algorithm> # ...

  4. Complete Tripartite

    D - Complete Tripartite 思路:这个题是个染色问题.理解题意就差不多写出来一半了.开始的时候还想用离散化来储存每个点的状态,即它连接的点有哪些,但很无奈,点太多了,long lo ...

  5. Codeforces Round #566 (Div. 2)

    Codeforces Round #566 (Div. 2) A Filling Shapes 给定一个 \(3\times n\) 的网格,问使用 这样的占三个格子图形填充满整个网格的方案数 如果 ...

  6. uva-122 Trees on the level(树的遍历)

    题目: 给出一棵树的表示,判断这棵树是否输入正确,如果正确就按层次遍历输出所有的结点,错误的话就输出not complete. 思路: 根据字符串中树的路径先将树建起来,在增加结点和层次遍历树的时候判 ...

  7. Codeforces Round #566 (Div. 2)题解

    时间\(9.05\)好评 A Filling Shapes 宽度为\(3\),不能横向填 考虑纵向填,长度为\(2\)为一块,填法有两种 如果长度为奇数则显然无解,否则\(2^{n/2}\) B Pl ...

  8. GreenPlum failover,primary和mirror切换实验 -- 重要

    GP failover,primary和mirror切换实验 http://blog.sina.com.cn/s/blog_9869114e0101k1nc.html 一.恢复失败的segment出现 ...

  9. swjtuoj2433 Magic Mirror

    描述 Magic Mirror is an artificial intelligence system developed by TAL AI LAB,It can determine human ...

随机推荐

  1. python 正则表达式 re.sub & re.subn

    Grammar: re.sub(pattern, repl, string[, count]) 使用repl替换string中每一个匹配的子串后返回替换后的字符串.当repl是一个字符串时,可以使用\ ...

  2. layui中获取全部提交的数据

    <form class="layui-form" action="">...........input textarea ......</fo ...

  3. js导入外部文件

  4. oracle--角色权限

    将不同权限赋予角色,再将角色赋予用户,起到管理权限的作用 SQL> create role myrole; 角色已创建. SQL> grant create session to myro ...

  5. [Python3 填坑] 017 实例方法、静态方法、类方法的区别

    目录 1. print( 坑的信息 ) 2. 开始填坑 2.1 先上例子 2.2 分析 1. print( 坑的信息 ) 挖坑时间:2019/04/07 明细 坑的编码 内容 Py024-1 实例方法 ...

  6. Forbidden (CSRF token missing or incorrect.):错误解决办法

    在JS中,使用post方法提交数据到后台,出现错误: Forbidden (CSRF token missing or incorrect.):.........; 解决办法: 在页面导入JS的位置, ...

  7. springboot多数据源&动态数据源(主从)

    多数据源 使用Spring Boot时,默认情况下,配置DataSource非常容易.Spring Boot会自动为我们配置好一个DataSource. 如果在application.yml中指定了s ...

  8. Linux常用指令全集

    Linux简介及Ubuntu安装 常见指令 系统管理命令 打包压缩相关命令 关机/重启机器 Linux管道 Linux软件包管理 vim使用 用户及用户组管理 文件权限管理 大牛笔记-www.weix ...

  9. Android客户端与Python服务器端通信之上传图片

    继上篇成功的与服务器端通信上之后,我现在需要将安卓本地的图片上传到服务端.服务端接收图片存下来. 参考:https://blog.csdn.net/qq_26906345/article/detail ...

  10. Python之路-pandas包的详解与使用

    什么是pandas pandas是一种Python数据分析的利器,是一个开源的数据分析包,最初是应用于金融数据分析工具而开发出来的,因此pandas为时间序列分析提供了很好的支持.pandas是PyD ...