(点击此处查看原题)

题目分析

题意:在一个树中,有n个结点,记为 1~n ,其中根结点编号为1,每个结点都有一个值val[i],问从根结点到各个结点的路径中所有结点的值的gcd(最大公约数)最大是多少,其中,我们可以将路径中某一个结点的值变为0,也可以选择不变。

思路:注意到对于每个结点,我们可以选择这个结点,或者不选这个结点(将权值记为0),因而有点01背包的感觉,而我们求gcd的时候需要取所有情况中的最大值

那么我们从根结点开始,每经过一个结点,就从其父节点的所有情况转移得到当前结点的状态,而对于每个结点所含有的状态,有如下三种

1)从根结点到当前结点,没有将任一结点的值变为0的情况下得到的gcd

2)从根结点到当前结点,选取除当前结点外的所有结点得到的gcd,也就是将当前结点的值当作0

3)由其父节点的所有情况转移而来,由于父节点的情况中一定会有不选取从根结点到父节点途中某点的情况,那么我们由父结点向当前结点转移得到的gcd(当前结点的值不当作0),代表不选取根结点到当前结点途中某点的情况。

这三种情况实际上整合为两种情况,即是由父结点转移到当前点的过程中,是否选择当前结点的两种情况,不过有的情况下我们必须选取当前结点,所以为了避免这种麻烦的判断,写为三种情况。

最后,我们取每个点所有情况下的最大值即可,不过为了节省时间和空间,我们用set对每个结点的状态去重。

(吐槽:个人感觉这种写法有TLE的嫌疑,又或者这个题的数据有点水....)

代码区

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<string>
#include<fstream>
#include<vector>
#include<stack>
#include <map>
#include <iomanip>
#include<set>
#include<cmath> #define bug cout << "**********" << endl
#define show(x, y) cout<<"["<<x<<","<<y<<"] "
#define LOCAL = 1;
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll mod = ;
const int Max = 2e5 + ;
const int Max2 = 1e3 + ; struct Edge
{
int to, next;
} edge[Max << ]; int n;
int head[Max], tot;
int val[Max], beauty[Max];
set<int> s[Max]; void init()
{
memset(head, -, sizeof(head));
tot = ;
for (int i = ; i <= n; i++)
s[i].clear();
} void add(int u, int v)
{
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
} int gcd(int a, int b)
{
if (a < b)
swap(a, b);
if (b == )
return a;
return gcd(b, a % b);
} void dfs(int u, int fa, int now)
{
for (auto it:s[fa])
{
s[u].insert(gcd(it, val[u])); //选取当前数,更新由父结点转移来的所有情况
}
s[u].insert(now); //不选当前结点
now = gcd(now,val[u]); //now代表的是没有删除任何点的情况下的gcd
s[u].insert(now); //不删除任何点 for (int i = head[u]; i != -; i = edge[i].next)
{
int v = edge[i].to;
if (v == fa)
continue;
dfs(v, u, now);
}
} int main()
{
#ifdef LOCAL
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
#endif
while (scanf("%d", &n) != EOF)
{
init();
for (int i = ; i <= n; i++)
{
scanf("%d", val + i);
}
for (int i = , u, v; i < n; i++)
{
scanf("%d%d", &u, &v);
add(u, v);
add(v, u);
}
dfs(, , );
for (int i = ; i < n; i++)
{
printf("%d ", *s[i].rbegin());
}
printf("%d\n",*s[n].rbegin());
}
return ;
}

codeforces 842C Ilya And The Tree (01背包+dfs)的更多相关文章

  1. codeforces 842C Ilya And The Tree

    Ilya is very fond of graphs, especially trees. During his last trip to the forest Ilya found a very ...

  2. Codeforces 842C Ilya And The Tree 树上gcd

    题目链接 题意 给定一棵根为\(1\)的树.定义每个点的美丽值为根节点到它的路径上所有点的\(gcd\)值.但是对于每个点,在计算它的美丽值时,可以将这条路径上某个点的值变为\(0\)来最大化它的美丽 ...

  3. [Swust OJ 465]--吴奶奶买鱼(0-1背包+dfs)

    题目链接:http://acm.swust.edu.cn/problem/465/ 还有一道题只是描述不一样,方法一模一样(http://acm.swust.edu.cn/problem/644/) ...

  4. hdu3448 01背包+dfs

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=3448 Description 0/1 bag problem should sound f ...

  5. POJ3628 Bookshelf 2(01背包+dfs)

    Bookshelf 2 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8745   Accepted: 3974 Descr ...

  6. HDU_2079_(01背包)(dfs)

    选课时间(题目已修改,注意读题) Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  7. CodeForces 682C Alyona and the Tree (树+dfs)

    Alyona and the Tree 题目链接: http://acm.hust.edu.cn/vjudge/contest/121333#problem/C Description Alyona ...

  8. Codeforces 682C Alyona and the Tree (树上DFS+DP)

    题目链接:http://codeforces.com/problemset/problem/682/C 题目大意:取树上任意一个点v,若点v的子树中有一个点u使得dist(v,u)>a[u]那么 ...

  9. CodeForces 682C Alyona and the Tree (树上DFS)

    题意:给定一棵树,每个叶子有一个权值,每条边也有一个权值,现在让你删最少的结点,使得从任何结点出发到另一个结点的边上权值和都小于两个结点的权值. 析:很明显是DFS,不过要想找出最少的结点可能不太容易 ...

随机推荐

  1. python3.*之列表常用操作

    首先定义一个列表:names= ["xiaoming","xiaogang","xiaomei","xiaohong"] ...

  2. [学习笔记] L1-PCA

    L1-PCA Intro PCA的本质就是从高维空间向低维空间投影,投影的本质又是左乘(或右乘)一个向量(表征原来特征空间到投影后特征空间的权重),经过线性加权,转换到低维空间表征,如果将向量换成矩阵 ...

  3. leetcode-hard-array-454 4sum II-NO

    mycode   过不了...我也不知道为什么... class Solution(object): def fourSumCount(self, A, B, C, D): ""& ...

  4. 在已开启Chrome窗口上调试

    代码 @Test void testNow() { /* First: Add the chrome.exe to the PATH. * Then: open the cmd and input t ...

  5. SprintBoot日志

    yml配置 #logging logging.file: "logs/app.log" logging: level: root: debug file: max-size: 10 ...

  6. [占位符 &nbsp; ]

    在做项目的时候,数据库中的数据会存在空值;这样,我们需要在前台给它加以判断, 如果我们不加以判断也是可行的,我们需要添加一个空白占位符  空白占位符 是个不错的选择,这样我们的页面显示数据的时候就不会 ...

  7. Json文件删除元素

    方法1:delete 注意,该方法删除之后的元素会变为null,并非真正的删除!!! 举例: 原json: { "front" : { "image" : [ ...

  8. NDk的目录

    * docs : 开发文档* build: linux下编译的批处理命令* platform : 某种平台下编译需要的头文件和函数库* prebuild : 预编译的工具* sample: 实例代码* ...

  9. 使用ViewFlipper实现广告图片的自动轮播的效果

    轮播资源图片的实现 package com.loaderman.viewflipperdemo; import android.os.Bundle; import android.support.v7 ...

  10. Host key verification failed

    一.发现问题 问题如下图代码: 这里面,有一句很关键. ECDSA host key for 108.61.163.242 has changed and you have requested str ...