题目: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. 新手解惑:nginx&php-fpm&fastcgi 是什么关系

    首先,CGI是干嘛的?CGI是为了保证web server传递过来的数据是标准格式的,方便CGI程序的编写者.   web server(比如说nginx)只是内容的分发者.比如,如果请求/index ...

  2. protel封装总结(新手必看)

    零件封装是指实际零件焊接到电路板时所指示的外观和焊点的位置.是纯粹的空间概念.因此不同的元件可共用同一零件封装,同种元件也可有不同的零件封装.像电阻,有传统的针插式,这种元件体积较大,电路板必须钻孔才 ...

  3. linux(centos7.0以上)下对mysql数据库的导入导出

    1:查看mysql安装路径: 指令 ps -ef|grep mysql 得出结果 root 968 1 0 18:25 ? 00:00:00 /bin/sh /usr/local/mysql/bin/ ...

  4. linux如何处理多连接请求?

    1.TCP迭代服务器程序 这种方式就是服务器同一时间只处理一个客户端的请求,这个请求处理完以后才转向下一个客户请求.当然这样的服务器程序比较少见,这就像一个公司只能一次处理一个客户,后面的客户只能等待 ...

  5. C#建造者模式

    /// <summary> /// 电脑类 /// </summary> public class Computer { //电脑组件集合 private IList<s ...

  6. (4.30)全面了解触发器:DML、DDL、LOGON触发器

    DML.DDL.LOGON触发器 转自:https://www.cnblogs.com/seusoftware/p/9120632.html 触发器可以理解为由特定事件触发的存储过程, 和存储过程.函 ...

  7. [2019杭电多校第六场][hdu6635]Nonsense Time

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6635 题意是说一开始所有数都冻结,第i秒会解冻第ki个数,求每秒状态下的最长上上升子序列长度. 这种题 ...

  8. [Codeforces 1199D]Welfare State(线段树)

    [Codeforces 1199D]Welfare State(线段树) 题面 给出一个长度为n的序列,有q次操作,操作有2种 1.单点修改,把\(a_x\)修改成y 2.区间修改,把序列中值< ...

  9. P2517 [HAOI2010]订货(dp)

    P2517 [HAOI2010]订货 设$f[i][j]$表示第$i$个月,库存为$j$的最小代价 枚举上个月的库存$k$,那么$f[i][j]=f[i-1][k]+(j+U[i]-k)*D[i]+j ...

  10. ofbiz idea 启动

    1.下载gradle并安装到本地 2.idea引入gradle 3.gradle右键选择refresh,项目会重新编译并加载gradle的task 4.可以再编译一下 5.没问题的话打开,jar ap ...