题意:

给定一棵树,每次可以拆掉一个树上度数为偶数的点,拆掉该点后,与该点所连的所有边都会被删掉。问,是否有一种删点顺序可以删掉所有的点。如果有,则输出任意一组解。

数据范围:线性做法 O(n)O(n)O(n)

不妨从叶子节点开始考虑问题。不难证明,距叶子节点最近的一个偶点一定要在删除父节点之前被删掉,因为如果先删除父节点则原偶点及其子树中所有点的度数都会是基数。

值得注意的是,每次选择的一定是深度最大的叶节点,所以我们要在 dfsdfsdfs 序上进行操作

我们可以在树的 dfsdfsdfs 序上进行操作。然后对第一个偶点进行 dfsdfsdfs,dfsdfsdfs 的过程中将所有偶点加入到答案队列中,并将第一个找到的偶点与父节点分离。这样,父节点有成为了全新的叶节点,并如此反复下去即可。

时间复杂度为 O(n)O(n)O(n)。

Code:

#include<cstdio>
#include<stack>
#include<queue>
using namespace std;
const int maxn = 500000 + 5;
int head[maxn], to[maxn << 1], nex[maxn << 1], cnt, degree[maxn], parent[maxn], vis[maxn];
stack<int>dfs; queue<int> answer;
inline void add_edge(int u,int v)
{
nex[++cnt] = head[u];
head[u] = cnt;
to[cnt] = v;
}
void dfs1(int u,int fa)
{
dfs.push(u); parent[u] = fa;
for(int v = head[u]; v ; v = nex[v]) if(to[v] != fa) dfs1(to[v], u);
}
void dfs2(int u)
{
answer.push(u); vis[u] = 1;
for(int v = head[u]; v ; v = nex[v]){
--degree[to[v]];
if(to[v] == parent[u] || vis[to[v]]) continue;
if(degree[to[v]] % 2 == 0) dfs2(to[v]);
}
}
int main()
{ int n; scanf("%d",&n);
for(int i = 1;i <= n; ++i){ int a; scanf("%d",&a); if(a == 0) continue; add_edge(i,a); add_edge(a,i); ++degree[a], ++degree[i]; }
dfs1(1, 0);
while(dfs.size())
{
int u = dfs.top(); dfs.pop();
if(degree[u] % 2 == 0) dfs2(u);
}
if(answer.size() == n)
{
printf("YES\n");
while(!answer.empty()){ printf("%d\n",answer.front()); answer.pop();}
}
else printf("NO");
return 0;
}

D. Destruction of a Tree_dfs序_性质分析_思维题的更多相关文章

  1. BZOJ 1108: [POI2007]天然气管道Gaz 性质分析_小结论_巧妙

    Description Mary试图控制成都的天然气市场.专家已经标示出了最好的天然气井和中转站在成都的地图.现在需要将中转 站和天然气井连接起来.每个中转站必须被连接到正好一个钻油井,反之亦然. M ...

  2. CF1168B Good Triple 性质分析_好题

    题意翻译 给出01串s,求数对[l,r]个数,使得能找到至少一对[x,k],使1<=x,k<=|s|且l<=x<x+2k<=r且s[x]=s[x+k]=s[x+2k] 题 ...

  3. cb34a_c++_STL_算法_查找算法_(7)_lower_bound

    cb34a_c++_STL_算法_查找算法_(7)_lower_bound//针对已序区间的查找算法,如set,multiset关联容器-自动排序lower_bound()--第一个可能的位置uppe ...

  4. cb33a_c++_STL_算法_查找算法_(6)binary_search_includes

    cb33a_c++_STL_算法_查找算法_(6)binary_search_includes//针对已序区间的查找算法,如set,multiset关联容器-自动排序binary_search(b,e ...

  5. cb32a_c++_STL_算法_查找算法_(5)adjacent_find

    cb32a_c++_STL_算法_查找算法_(5)adjacent_findadjacent_find(b,e),b,begin(),e,end()adjacent_find(b,e,p),p-par ...

  6. cb28a_c++_STL_算法_查找算法_(1)find_find_if

    cb28a_c++_STL_算法_查找算法_(1)find_find_iffind() //线性查找,比较慢.pos1 = find(ilist.begin(), ilist.end(), 5);fi ...

  7. 日志分析_使用shell完整日志分析案例

    一.需求分析 1. 日志文件每天生成一份(需要将日志文件定时上传至hdfs) 2. 分析日志文件中包含的字段:访问IP,访问时间,访问URL,访问状态,访问流量 3. 现在有"昨日" ...

  8. Spring_MVC_教程_快速入门_深入分析

    Spring MVC 教程,快速入门,深入分析 博客分类: SPRING Spring MVC 教程快速入门  资源下载: Spring_MVC_教程_快速入门_深入分析V1.1.pdf Spring ...

  9. 基于samba实现win7与linux之间共享文件_阳仔_新浪博客

    基于samba实现win7与linux之间共享文件_阳仔_新浪博客 然后启动samba执行如下指令: /dev/init.d/smb start 至此完成全部配置.

随机推荐

  1. 什么是JSON ?

    JSON 实例 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <t ...

  2. 训练1-J

    把一个偶数拆成两个不同素数的和,有几种拆法呢? Input 输入包含一些正的偶数,其值不会超过10000,个数不会超过500,若遇0,则结束. Output 对应每个偶数,输出其拆成不同素数的个数,每 ...

  3. P1422 小玉家的电费

    ... 题目描述 夏天到了,各家各户的用电量都增加了许多,相应的电费也交的更多了.小玉家今天收到了一份电费通知单.小玉看到上面写:据闽价电[2006]27号规定,月用电量在150千瓦时及以下部分按每千 ...

  4. RobotFrameWork+APPIUM实现对安卓APK的自动化测试----第三篇【实例】

    http://blog.csdn.net/deadgrape/article/details/50579565 在这一篇里我先让大家看一下RF+APPIUM这个框架的实际运行时什么样子的,给大家一个直 ...

  5. PHP 防xss攻击

    PHP直接输出html的,可以采用以下的方法进行过滤: 1.htmlspecialchars函数 2.htmlentities函数 3.HTMLPurifier.auto.php插件 4.Remove ...

  6. iwebshop 增删改查

    <?php header("content-type:text/html;charset=utf-8"); class Test extends IController { ...

  7. ASP.NET-AD开发技巧

    分享一篇很好的介绍AD属性的文章 AD图片插件 如何给AD添加图片 http://www.doc88.com/p-9542932844870.html AD过滤条件 重命名ou使用user.Renam ...

  8. nodejs-配置vs code的插件

    在windows上安装好npm后,再在终端里使用npm安装express,再安装express-generator  进入express的目录, 在终端中执行 npm install 启动expres ...

  9. [HTML5]构建离线web应用程序

    1.检查浏览器是否支持缓存 if(window.applicationCache){ //TODO } 2.在html中加入manifest特性 <html manifest="app ...

  10. Rails中关联数据表的添加操作(嵌套表单)

    很早就听说有Web敏捷开发这回事,最近终于闲了下来,可以利用业余的时间学些新东西,入眼的第一个东东自然是Ruby on Rails.Rails中的核心要素也就是MVC.ORM这些了,因此关于Rails ...