CF1182 D Complete Mirror——思路
题目: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——思路的更多相关文章
- Codeforces 1182D Complete Mirror [树哈希]
Codeforces 中考考完之后第一个AC,纪念一下qwq 思路 简单理解一下题之后就可以发现其实就是要求一个点,使得把它提为根之后整棵树显得非常对称. 很容易想到树哈希来判结构是否相同,而且由于只 ...
- Codeforces 1182D Complete Mirror 树的重心乱搞 / 树的直径 / 拓扑排序
题意:给你一颗树,问这颗树是否存在一个根,使得对于任意两点,如果它们到根的距离相同,那么它们的度必须相等. 思路1:树的重心乱搞 根据样例发现,树的重心可能是答案,所以我们可以先判断一下树的重心可不可 ...
- cf1182D Complete Mirror
可以得到一个结论, 可行的点要么是直径端点, 要么是直径中点, 要么是直径中点引出的链中最短的端点 #include<cstdio> #include<algorithm> # ...
- Complete Tripartite
D - Complete Tripartite 思路:这个题是个染色问题.理解题意就差不多写出来一半了.开始的时候还想用离散化来储存每个点的状态,即它连接的点有哪些,但很无奈,点太多了,long lo ...
- Codeforces Round #566 (Div. 2)
Codeforces Round #566 (Div. 2) A Filling Shapes 给定一个 \(3\times n\) 的网格,问使用 这样的占三个格子图形填充满整个网格的方案数 如果 ...
- uva-122 Trees on the level(树的遍历)
题目: 给出一棵树的表示,判断这棵树是否输入正确,如果正确就按层次遍历输出所有的结点,错误的话就输出not complete. 思路: 根据字符串中树的路径先将树建起来,在增加结点和层次遍历树的时候判 ...
- Codeforces Round #566 (Div. 2)题解
时间\(9.05\)好评 A Filling Shapes 宽度为\(3\),不能横向填 考虑纵向填,长度为\(2\)为一块,填法有两种 如果长度为奇数则显然无解,否则\(2^{n/2}\) B Pl ...
- GreenPlum failover,primary和mirror切换实验 -- 重要
GP failover,primary和mirror切换实验 http://blog.sina.com.cn/s/blog_9869114e0101k1nc.html 一.恢复失败的segment出现 ...
- swjtuoj2433 Magic Mirror
描述 Magic Mirror is an artificial intelligence system developed by TAL AI LAB,It can determine human ...
随机推荐
- Leaflet
https://leafletjs.com/ https://github.com/Leaflet/Leaflet
- 优化 | Redis AOF重写导致的内存问题 不错
一.问题说明 业务上接到报警提示服务器内存爆了,登录查看发现机器剩余内存还很多,怀疑是被OOM了,查看/var/log/messages: kernel: [25918282.632003] Out ...
- docker搭建一个渗透测试环境 bwapp为例
bwapp是一个渗透测试靶场,他其中中含有100多个Web漏洞 基本涵盖了所有主要的已知Web漏洞,包括OWASP Top 10的各种 首先要去搜索一下 看一下有哪些镜像可以下载 docke ...
- Java学习day7面向对象编程1-对象和类
一.Java编程中对象和类的概念 1,什么是类? 答:类是客观存在的,抽象的,概念的东西. 2,什么是对象? 答:对象是具体的,实际的,代表一个事物.例如:车是一个类,汽车,自行车就是他的对象. 关于 ...
- [BZOJ 3295] [luogu 3157] [CQOI2011]动态逆序对(树状数组套权值线段树)
[BZOJ 3295] [luogu 3157] [CQOI2011] 动态逆序对 (树状数组套权值线段树) 题面 给出一个长度为n的排列,每次操作删除一个数,求每次操作前排列逆序对的个数 分析 每次 ...
- P5504 [JSOI2011]柠檬
传送门 显然考虑 $dp$ ,发现从右往左和从左往右是一样的,所以只考虑一边就行 发现对于切的左右端点,选择的 $s0$ 一定要为左右端点的贝壳大小,不然这个端点不产生贡献还不如分开来单个贡献 所以设 ...
- html表格单元格添加斜下框线的方法
一.分隔单元格的方法 1.用“transform: rotate(-55deg);”把一条水平线旋转一定角度就成斜线了 2.利用以下命令调整分割线位置等. :after :before transfo ...
- MVC 与 MVP 并无两样
关于 MVC 的定义介绍,摘一段百度百科介绍: MVC 是一种使用 MVC(Model View Controller 模型-视图-控制器)设计创建 Web 应用程序的模式: Model(模型)表示应 ...
- 【转】DDR3和eMMC区别
转自:https://www.cnblogs.com/debruyne/p/9186619.html DDR3内存条和eMMC存储器区别: 1. 存储性质不同:2. 存储容量不同:3. 运行速度不同: ...
- 【改】shell 判断文件中有无特定子串方法(grep)
转自:https://blog.csdn.net/zhuguiqin1/article/details/79160923 利用grep执行的命令结束代码$?的值来判断是否已经grep到特定的值. 当$ ...