zoukankan      html  css  js  c++  java
  • CF842C Ilya And The Tree

    思路:

    1. 如果根节点是0,那么可以通过一次dfs计算出所有节点的最大值。

    2. 如果根节点不是0,那么其余各点的最大值一定是根节点的一个因子。首先计算出根节点的所有因子。在dfs到一个深度为d的节点v时,遍历所有因子:对于因子x,p表示从根节点到达v的路径中能够被x整除的节点个数。如果p >= d - 1,则x就是当前节点的一个候选最大值(d-1是因为可以把路径中其中一个数替换为0)。

    于是通过两次dfs即可得出答案。复杂度O(n * sqrt(n))。在dfs的过程中,要注意维护全局变量。dfs到下一个分支时,要把上一个分支对全局变量造成的影响消除。

    实现:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 int a[200005], val[200005];
     4 vector<int> tree[200005];
     5 int vis[200005];
     6 int divisors[1005];
     7 
     8 void dfs(int cur, int div)
     9 {
    10     vis[cur] = 1;
    11     for (int i = 0; i < tree[cur].size(); i++)
    12     {
    13         int tmp = tree[cur][i];
    14         if (vis[tmp]) continue;
    15         val[tmp] = __gcd(div, a[tmp]);
    16         dfs(tmp, val[tmp]);
    17     }
    18 }
    19 
    20 void dfs2(int cur, int d, vector<int>& v)
    21 {
    22     vis[cur] = 1;
    23     for (int i = 0; i < tree[cur].size(); i++)
    24     {
    25         int tmp = tree[cur][i];
    26         if (vis[tmp]) continue;
    27          for (int j = 0; j < v.size(); j++)
    28         {
    29             if (a[tmp] % v[j] == 0) divisors[j]++;
    30             if (divisors[j] >= d) val[tmp] = max(val[tmp], v[j]);
    31         }
    32         dfs2(tmp, d + 1, v);
    33         for (int j = 0; j < v.size(); j++)
    34             if (a[tmp] % v[j] == 0) divisors[j]--;
    35     }
    36 }
    37 
    38 int main()
    39 {
    40     int n, x, y;
    41     while (cin >> n)
    42     {
    43         for (int i = 1; i <= n; i++)
    44             tree[i].clear();
    45         for (int i = 1; i <= n; i++)
    46             cin >> a[i];
    47         for (int i = 0; i < n - 1; i++)
    48         {
    49             cin >> x >> y;
    50             tree[x].push_back(y);
    51             tree[y].push_back(x);
    52         }
    53         int tmp = a[1];
    54         a[1] = 0;
    55         memset(vis, 0, sizeof vis);
    56         dfs(1, 0);
    57         a[1] = val[1] = tmp;
    58         vector<int> v;
    59         for (int i = 1; i * i <= a[1]; i++)
    60         {
    61             if (a[1] % i == 0)
    62             {
    63                 v.push_back(i);
    64                 if (a[1] / i != i) v.push_back(a[1] / i);
    65             }
    66         }
    67         sort(v.begin(), v.end());
    68         for (int i = 0; i < v.size(); i++) divisors[i] = 1;
    69         memset(vis, 0, sizeof vis);
    70         dfs2(1, 1, v);
    71         for (int i = 1; i <= n; i++)
    72             cout << val[i] << " ";
    73         cout << endl;
    74     }
    75     return 0;
    76 }
  • 相关阅读:
    软件工程课程-助教自我介绍
    软件工程课程-课代表信息
    软件工程课程-课后作业
    小知识记录:第四篇
    小知识记录:第三篇
    小知识记录:第二篇
    小知识记录:第一篇
    dd命令和fio命令测试磁盘io性能
    horizon仪表盘安装
    OpenStack安装部署笔记
  • 原文地址:https://www.cnblogs.com/wangyiming/p/7469569.html
Copyright © 2011-2022 走看看