• 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 }
  • 相关阅读:
    数据库MySQL技术-基础知识
    NC文件的处理【netcdf】
    设计模式-策略模式---Strategy(对象行为型)
    final修饰的变量是引用不能改变,还是引用的对象不能改变
    Spring之配置文件加载方式
    hibernate的基础学习--多表关联数据查询
    hibernate的基础学习--多对多关联
    hibernate的基础学习--一对一关联
    hibernate的基础学习--一对多关联
    hibernate的基础学习
  • 原文地址:https://www.cnblogs.com/liulangye/p/12161952.html
Copyright © 2020-2023  润新知