题目: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. http://blog.csdn.net/sdksdk0/article/details/50749326

    http://blog.csdn.net/sdksdk0/article/details/50749326

  2. MFC下一个通用非阻塞的等待执行结束的对话框类

    头文件:CPictureEx用于显示一个等待动画 #pragma once #include "afxwin.h" #include "resource.h" ...

  3. 关于微信授权和unionid 的获取思路。

    1.首先根据appid 获取到预授权码的code string Appid = "******";//appid.由于网页授权与js-jdk使用不同微信,所以暂时独立于此处. st ...

  4. [CCPC-Wannafly & Comet OJ 夏季欢乐赛(2019)]飞行棋

    题目链接:https://www.cometoj.com/contest/59/problem/E?problem_id=2714 求期望并且一堆转移基本上就是期望dp了(叉腰 照常的设dp[i]表示 ...

  5. docker私有仓库部署

    首先科普docker几种“仓库”概念,可分为:本地镜像,本地仓库,公有仓库(docker hub) 本地镜像:在把java程序打包成镜像,输出的镜像的位置就是本地镜像 公有仓库:一个叫docker h ...

  6. C# Lodop与C-Lopdop选择打印机

    原文:https://www.cnblogs.com/huaxie/p/9766886.html https://www.cnblogs.com/huaxie/p/10857490.html http ...

  7. AppDomain (转)

    AppDomain是CLR的运行单元,它可以加载Assembly.创建对象以及执行程序.AppDomain是CLR实现代码隔离的基本机制. 每一个AppDomain可以单独运行.停止:每个AppDom ...

  8. 26、前端知识点--利用webpack搭建脚手架一套完整流程

    前言 我们的目标是利用webpack搭建一个基于react + react-router +dva + es6 + less + antd用于中后台开发的脚手架,同学们可能会说社区里那么多优秀的脚手架 ...

  9. 【推荐系统】知乎live入门4.排序

    参考链接 [推荐系统]知乎live入门 目录 1. 概述 2. 排序模型建模 3. 排序总结 ===================================================== ...

  10. HashMap对象转换为JavaBean对象

    问题: 在日常代码中,使用 spring包中的 BeanUtils.copyProperties(source,target),可以将A对象的属性复制到B对象中,但是有个问题 无法将HashMap中的 ...