题目: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. free pascal 修改字符集,会导致 dos 不能显示 汉字。 处理方法如下

    http://www.cnblogs.com/yjken/p/3917932.html 让windows系统的DOS窗口也可以显示utf8字符集   C:\Users\Administrator> ...

  2. ecshop后台增加模块菜单详细教程

    我们有时候针对ecshop如此开发,想在后台加一些菜单,最模板以前提供过教程,但是并非很系统,今天最模板抛砖引玉图文教程告诉大家:如何在ecshop后台增加模块菜单! 首先需要修改四个文件:inc_p ...

  3. IntelliJ IDEA的常用设置

    1.设置IDEA主题样式 ①设置方法: ②效果:设置为Darcula之后整体的风格就是暗黑主题,如上图. 2.设置编辑区主题 ①设置方法: 注:由于IDEA自带的编辑区主题比较少,想要更多的编辑区主题 ...

  4. 5款vue前端UI框架

    Vue.js是一套构建用户界面的 渐进式框架.与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计. 实用的 Vue.js组件库可以帮助我们快速搭建页面,下面介绍小编认为比较受欢迎的五个vue ...

  5. WPF资源字典的使用

    1.在解决方案中添加资源字典:鼠标右键——添加——资源字典 2.在资源字典中写入你需要的样式,我这里简单的写了一个窗体的边框样式 3.在App.xaml中加入刚刚新建的资源字典就好了

  6. string类find_first_not_of ()方法

    string类find_first_not_of ()方法 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://xfqxj.blog. ...

  7. HDFS中NameNode和Secondary NameNode工作机制

    NameNode工作机制 0)启动概述 Namenode启动时,首先将映像文件(fsimage)载入内存,并执行编辑日志(edits)中的各项操作.一旦在内存中成功建立文件系统元数据的映像,则创建一个 ...

  8. <meta>标签中http-equiv属性的属性值X-UA-Compatible详解

    X-UA-Compatible是针对IE8新加的一个设置,对于IE8之外的浏览器是不识别的,这个区别与content="IE=7"在无论页面是否包含<!DOCTYPE> ...

  9. php使用Socket实现聊天室功能(书中的代码)

    这只是一种技术 <?php $host = "127.0.0.1"; // 指定监听的端口,注意该端口不能与现有应用的端口冲突 $port = '9505'; $null = ...

  10. linux安装 inotify

    [root@rsync-client-inotify ~]# yum install make gcc gcc-c++ [root@rsync-client-inotify ~]# wget http ...