C. Ilya And The Tree 树形dp 暴力

Posted echozqn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C. Ilya And The Tree 树形dp 暴力相关的知识,希望对你有一定的参考价值。

C. Ilya And The Tree

写法还是比较容易想到,但是这么暴力的写法不是那么的敢写。

就直接枚举了每一个点上面的点的所有的情况,对于这个点不放进去特判一下,然后排序去重提高效率。

注意dp[v]一开始存的是从根节点到这个节点都选的情况,这样才好往后转移。

技术图片
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 4e5 + 10;
typedef long long ll;
int dp[maxn], head[maxn], cnt = 0, a[maxn];
vector<int>vec[maxn];
struct node

    int u, v, nxt;
    node(int u=0,int v=0,int nxt=0):u(u),v(v),nxt(nxt)
ex[maxn];

void init()

    memset(head, -1, sizeof(head));
    cnt = 0;

void add(int u,int v)

    ex[cnt] = node(u, v, head[u]);
    head[u] = cnt++;
    ex[cnt] = node(v, u, head[v]);
    head[v] = cnt++;


int gcd(int a,int b)

    return b == 0 ? a : gcd(b, a%b);


void dfs(int u,int pre)

    for(int i=head[u];i!=-1;i=ex[i].nxt)
    
        int v = ex[i].v;
        if (v == pre) continue;
        dp[v] = gcd(dp[u], a[v]);
        vec[v].push_back(dp[u]);
        for(int j=0;j<vec[u].size();j++) vec[v].push_back(gcd(vec[u][j], a[v]));
        sort(vec[v].begin(), vec[v].end());
        vec[v].erase(unique(vec[v].begin(), vec[v].end()), vec[v].end());
        dfs(v, u);
    


int main()

    init();
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    for(int i=1;i<n;i++)
    
        int u, v;
        scanf("%d%d", &u, &v);
        add(u, v);
    
    dp[1] = a[1];
    vec[1].push_back(0);
    dfs(1, -1);
    for (int i = 1; i <= n; i++) dp[i] = max(dp[i], vec[i].back());
    for (int i = 1; i <= n; i++) printf("%d ", dp[i]);
    return 0;
View Code

 

以上是关于C. Ilya And The Tree 树形dp 暴力的主要内容,如果未能解决你的问题,请参考以下文章

CF 842C Ilya And The Tree(树上DFS)

[CF842C]Ilya And The Tree

Ilya And The Tree CodeForces - 842C

CF842C Ilya And The Tree

C - Ilya And The Tree Codeforces Round #430 (Div. 2)

codeforces 842C Ilya And The Tree (01背包+dfs)