C. Ilya And The Tree 树形dp 暴力

末鹿安然 提交于 2019-11-28 00:10:51

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

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!