Codeforces Round #475 (Div. 2) D. Destruction of a Tree

 1 You are given a tree (a graph with n vertices and n?-?1 edges in which it‘s possible to reach any vertex from any other vertex using only its edges).
 2
 3 A vertex can be destroyed if this vertex has even degree. If you destroy a vertex, all edges connected to it are also deleted.
 4
 5 Destroy all vertices in the given tree or determine that it is impossible.
 6
 7 Input
 8 The first line contains integer n (1?≤?n?≤?2·105) — number of vertices in a tree.
 9
10 The second line contains n integers p1,?p2,?...,?pn (0?≤?pi?≤?n). If pi?≠?0 there is an edge between vertices i and pi. It is guaranteed that the given graph is a tree.
11
12 Output
13 If it‘s possible to destroy all vertices, print "YES" (without quotes), otherwise print "NO" (without quotes).
14
15 If it‘s possible to destroy all vertices, in the next n lines print the indices of the vertices in order you destroy them. If there are multiple correct answers, print any.
16
17 Examples
18 inputCopy
19 5
20 0 1 2 1 2
21 outputCopy
22 YES
23 1
24 2
25 3
26 5
27 4
28 inputCopy
29 4
30 0 1 2 3
31 outputCopy
32 NO

题目大意:有n个顶点,输入n个数字,记作p[i],如果p[i]!=0,则表示有一条i到p[i]的边,要求你输出删除顶点的顺序,删除的条件有:1。这个点必须有偶数条边才能被删除  2。跟删除点连接的边都要去掉

分析:用一个in[maxn]的数组来记录连接u点的边数是偶数还是奇数,然后用dfs来跑遍所有的路,求出所有顶点是奇数还是偶数,最后递归打印即可

  1 #define debug
  2 #include<stdio.h>
  3 #include<math.h>
  4 #include<cmath>
  5 #include<queue>
  6 #include<stack>
  7 #include<string>
  8 #include<cstring>
  9 #include<string.h>
 10 #include<algorithm>
 11 #include<iostream>
 12 #include<vector>
 13 #include<functional>
 14 #include<iomanip>
 15 #include<map>
 16 #include<set>
 17 #define pb push_back
 18 #define dbg(x) cout<<#x<<" = "<<(x)<<endl;
 19 using namespace std;
 20 typedef long long ll;
 21 typedef pair<int,int> pii;
 22 typedef pair<ll,ll>PLL;
 23 typedef pair<int,ll>Pil;
 24 const ll INF = 0x3f3f3f3f;
 25 const double inf=1e8+100;
 26 const double eps=1e-8;
 27 const int maxn =1e6;
 28 const int N = 510;
 29 const ll mod=1e9+7;
 30 //------
 31 //define
 32 bool ve[maxn];
 33 vector<int>G[maxn];
 34 int in[maxn];
 35 //dfs
 36 void dfs(int u) {
 37     for(int i=0; i<G[u].size(); i++) {
 38         int tmp=G[u][i];
 39         if(tmp==u)continue;
 40         dfs(tmp);
 41         in[u]^=in[tmp];
 42     }
 43     in[u]^=1;
 44 }
 45 void print(int u) {
 46     for(int i=0; i<G[u].size(); i++) {
 47         int tmp=G[u][i];
 48         if(tmp==u)continue;
 49         if(!in[tmp]) {
 50             print(tmp);
 51         }
 52     }
 53     cout<<u<<endl;
 54     for(int i=0; i<G[u].size(); i++) {
 55         int tmp=G[u][i];
 56         if(tmp==u)continue;
 57         if(in[tmp]) {
 58             print(tmp);
 59         }
 60     }
 61 }
 62 //solve
 63 void solve() {
 64     int n,s;
 65     cin>>n;
 66     for(int i=0; i<n; i++) {
 67         int u;
 68         cin>>u;
 69         if(u) {
 70             G[u].push_back(i+1);
 71         } else {
 72             s=i+1;
 73         }
 74     }
 75     dfs(s);
 76     if(in[s]) {
 77         cout<<"YES"<<endl;
 78         print(s);
 79     }else{
 80         cout<<"NO"<<endl;
 81     }
 82 }
 83 //main
 84 int main() {
 85     ios_base::sync_with_stdio(false);
 86 #ifdef debug
 87     freopen("in.txt", "r", stdin);
 88 //    freopen("out.txt","w",stdout);
 89 #endif
 90     cin.tie(0);
 91     cout.tie(0);
 92     solve();
 93     /*
 94         #ifdef debug
 95             fclose(stdin);
 96             fclose(stdout);
 97             system("out.txt");
 98         #endif
 99     */
100     return 0;
101 }

原文地址:https://www.cnblogs.com/visualVK/p/8893592.html

时间: 2024-10-08 03:07:25

Codeforces Round #475 (Div. 2) D. Destruction of a Tree的相关文章

Codeforces Round #417 (Div. 2) E. Sagheer and Apple Tree(树上Nim)

题目链接:Codeforces Round #417 (Div. 2) E. Sagheer and Apple Tree 题意: 给你一棵树,每个节点有a[i]个苹果,有两个人要在这个树上玩游戏. 两个人轮流操作,谁不能操作谁就输了. 这个树有一个特性:叶子到根的距离的奇偶性相同. 每次操作可以选一个节点i,和一个数x,x小于当前节点i的苹果数. 对于节点i,如果是叶子节点,就将这x个苹果吃掉. 如果是非叶子节点,就将这x个苹果移向节点i的任意儿子节点. 现在第二个操作的人要交换两个节点的苹果

Codeforces Round #475 (Div. 2) C - Alternating Sum

等比数列求和一定要分类讨论!!!!!!!!!!!! 1 #include<bits/stdc++.h> 2 #define LL long long 3 #define fi first 4 #define se second 5 #define mk make_pair 6 #define pii pair<int,int> 7 #define ull unsigned long long 8 using namespace std; 9 10 const int N=1e6+7

Educational Codeforces Round #54 (Div. 2) E. Vasya and a Tree 技巧題

題目連接:http://codeforces.com/contest/1076/problem/E 本題大意: 給一棵根節點為"1"樹,給m個操作,每個操作三個整數,v,d,x,意思是從節點1,往下深度d,遍及的節點的值都加上x,d可能是0,就是只加在自己上.結束m個操作后輸出每個節點的值. 解題思路: 這裡不應該考慮同時操作整棵樹.因為每個節點的子樹是多樣的,而應該以dfs的形式,直接搜到葉子節點,這樣沿途就是一條鏈.每時每刻都在操作一條鏈,也就是一段區間.這樣操作轉化為:一個節點往

Codeforces Round #530 (Div. 2):D. Sum in the tree (题解)

D. Sum in the tree 题目链接:https://codeforces.com/contest/1099/problem/D 题意: 给出一棵树,以及每个点的si,这里的si代表从i号结点到根节点的权值和.但是有些si=-1,这就相当于丢失了当前结点的数据. 假设原本每个点的权值为ai,那么现在求sum{ai}的最小为多少,ai为非负数. 题解: 这题可以单独看每一条链上的s值,假设当前结点为u,儿子结点v,那么就有几种情况: 1.su==-1&&sv==-1,这种不用管,继

Codeforces Round #291 (Div. 2) E - Darth Vader and Tree (DP+矩阵快速幂)

这题想了好长时间,果断没思路..于是搜了一下题解.一看题解上的"快速幂"这俩字,不对..这仨字..犹如醍醐灌顶啊...因为x的范围是10^9,所以当时想的时候果断把dp递推这一方法抛弃了.我怎么就没想到矩阵快速幂呢.......还是太弱了..sad..100*100*100*log(10^9)的复杂度刚刚好. 于是,想到了矩阵快速幂后,一切就变得简单了.就可以把距离<=x的所有距离的点数都通过DP推出来,然后一个快速幂就解决了. 首先DP递推式很容易想到.递推代码如下: for(

【树形DP】Codeforces Round #395 (Div. 2) C. Timofey and a tree

先把1看作根. 预处理出f[i]表示以i为根的子树是什么颜色,如果是杂色的话,就是0. 然后从根节点开始转移,转移到某个子节点时,如果其子节点都是纯色,并且它上面的那一坨结点也是纯色,就输出解. 否则如果其上面的一坨是纯色,并且其子节点有且只有一个杂色的时候,就递归处理该子节点. #include<cstdio> #include<cstdlib> using namespace std; #define N 100050 int v[N<<1],first[N],ne

(博弈\sg) Codeforces Round #417 (Div. 2) E Sagheer and Apple Tree

Sagheer is playing a game with his best friend Soliman. He brought a tree with n nodes numbered from 1 to n and rooted at node 1. The i-th node has ai apples. This tree has a special property: the lengths of all paths from the root to any leaf have t

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿