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 }

猜你喜欢

转载自www.cnblogs.com/liulangye/p/12161952.html