D. Numbers on Tree
Posted liulangye
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了D. Numbers on Tree相关的知识,希望对你有一定的参考价值。
http://codeforces.com/contest/1287/problem/D
思路:
1. 每个子树维护一个数组,包含所有节点的编号和值,且按值排序。
2. 每个子子树的数组需要合并到父节点表示的父子树中,合并需要维护按照值的递增顺序。
3. 所有子子树合并到当前节点表示的父子树中后需要确定当前节点的值,因为数组是有顺序的,所以直接插入到对应的位置就可以,然后值需要比前一个点的值+1,有序数组后续的点如果由小于当前点的值,则需要集体+1,这样就满足了所有子子树中有多少个点小于自己. 这种方式之所以正确是因为保证了每个子子树中任意两点之间的关系没有实质性的改变。
代码:
1 #include <iostream> 2 #include <string> 3 #include <string.h> 4 #include <stdio.h> 5 #include <algorithm> 6 #include <map> 7 #include <unordered_map> 8 #include <vector> 9 #include <stack> 10 11 using namespace std; 12 13 typedef long long LL; 14 15 const int N = 20001; 16 int ans[N]; 17 int f[N]; 18 int sub[N]; 19 int num[N]; 20 21 struct node 22 { 23 int g, index; 24 25 node(int g, int index) 26 :g(g), index(index) 27 {} 28 }; 29 vector<node> vt[N]; 30 31 void merge(vector<node>& f, vector<node>& s) 32 { 33 vector<node> tmp; 34 for (int i = 0, j = 0; i < f.size() || j < s.size(); ) 35 { 36 if (i >= f.size()) 37 { 38 tmp.push_back(s[j]); 39 j++; 40 continue; 41 } 42 if (j >= s.size()) 43 { 44 tmp.push_back(f[i]); 45 i++; 46 continue; 47 } 48 if (f[i].g < s[j].g) 49 { 50 tmp.push_back(f[i]); 51 i++; 52 } 53 else 54 { 55 tmp.push_back(s[j]); 56 j++; 57 } 58 } 59 f = move(tmp); 60 } 61 62 int main() 63 { 64 int n; 65 while (cin>>n) 66 { 67 memset(f, 0, sizeof(f)); 68 memset(num, 0, sizeof(num)); 69 memset(sub, 0, sizeof(sub)); 70 memset(ans, 0, sizeof(ans)); 71 for (int i = 0; i < N; ++i) 72 { 73 vt[i].clear(); 74 } 75 for (int i = 1; i <= n; ++i) 76 { 77 int p, k; 78 cin>>p>>k; 79 num[i] = k; 80 f[i] = p; 81 sub[p]++; 82 } 83 stack<int> st; 84 for (int i = 1; i <= n; ++i) 85 { 86 if (sub[i] == 0) 87 { 88 st.push(i); 89 } 90 } 91 bool has_ans = true; 92 while (!st.empty()) 93 { 94 int index = st.top(); 95 st.pop(); 96 97 int k = num[index]; 98 99 if (vt[index].size() < k) 100 { 101 has_ans = false; 102 break; 103 } 104 105 vt[index].insert(vt[index].begin() + k, node(0, index)); 106 for (int i = k; i < vt[index].size(); ++i) 107 { 108 if (i == k) 109 { 110 if (i - 1 >= 0) 111 { 112 vt[index][i].g = vt[index][i-1].g + 1; 113 } 114 else 115 { 116 vt[index][i].g = 1; 117 } 118 continue; 119 } 120 if (i == k+1) 121 { 122 if (vt[index][i].g >= vt[index][k].g) 123 { 124 break; 125 } 126 } 127 vt[index][i].g ++; 128 } 129 130 int p = f[index]; 131 if (0 == p) 132 { 133 for (int i = 0; i < vt[index].size(); ++i) 134 { 135 ans[vt[index][i].index] = vt[index][i].g; 136 } 137 break; 138 } 139 140 merge(vt[p], vt[index]); 141 142 sub[p]--; 143 if (0 == sub[p]) 144 { 145 st.push(p); 146 } 147 } 148 if (!has_ans) 149 { 150 cout << "NO" << endl; 151 } 152 else 153 { 154 cout << "YES" << endl; 155 for (int i = 1; i <= n; ++i) 156 { 157 cout << ans[i]; 158 if (i != n) 159 { 160 cout << " "; 161 } 162 } 163 cout << endl; 164 } 165 } 166 return 0; 167 }
以上是关于D. Numbers on Tree的主要内容,如果未能解决你的问题,请参考以下文章
D. Arpa and a list of numbers Codeforces Round #432 (Div. 2, based on IndiaHacks Final Round 2017)(示
Codeforces Round #468 (Div. 2, based on Technocup 2018 Final Round) D. Peculiar apple-tree