您的位置:首页 > 其它

CodeForces - 842C Ilya And The Tree 树上DFS

2017-09-05 12:33 417 查看
树上的 DFS ,

已知根结点,从根结点往下递归,dp 数组保存不对结点清零时的 gcd ,然后用 ok 数组保存每个结点的可能的情况,最后进行比较,得到 res 答案数组

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <ctype.h>
#include <vector>
#include <algorithm>
#include <sstream>
#define PI acos(-1.0)
#define in freopen("in.txt", "r", stdin)
#define out freopen("out.txt", "w", stdout)
using namespace std;
typedef long long ll;
const int maxn = 200000 + 7, INF = 0x3f3f3f3f, mod = 1e9 + 7;

int a[maxn], dp[maxn], res[maxn];
vector<int> e[maxn], ok[maxn];

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

void dfs(int u, int f) {
for(int i = 0; i < (int)e[u].size(); ++i) {
int v = e[u][i];
if(v == f) continue; // 父结点
dp[v] = gcd(dp[u], a[v]); // 全都不删时的 gcd
ok[v].push_back(dp[u]); // 删除当前边
for(int j = 0; j < (int)ok[u].size(); ++j) {
ok[v].push_back(gcd(a[v], ok[u][j]) );
}
sort(ok[v].begin(), ok[v].end()); // v 结点 的 answer
ok[v].erase(unique(ok[v].begin(), ok[v].end()), ok[v].end());
dfs(v, u);
}
}

int main() {
int n;
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
scanf("%d", &a[i]);
for(int i = 1; i < n; ++i) {
int x, y;
scanf("%d%d", &x, &y);
e[x].push_back(y);
e[y].push_back(x);
}
dp[1] = a[1];
ok[1].push_back(0);
dfs(1, 0);
for(int i = 1; i <= n; ++i) {
res[i] = dp[i];
if(!ok[i].empty())
res[i] = max(res[i], ok[i].back());
}
for(int i = 1; i <= n; ++i)
printf("%d ", res[i]);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: