zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    软件工程概论之web基础
    java动手动脑——异常处理
    Java动手动脑——多态和继承
    java字串
    数据结构——用栈来判断回文字符串
    java一个能记录生成多少个对象的类
    openwrt设置默认登陆密码
    在ubuntu中安装luci解决iwinfo.h No such file or directory问题
    添加mysamba
    更改默认打开wifi功能
  • 原文地址:https://www.cnblogs.com/liulangye/p/12161952.html
Copyright © 2011-2022 走看看