P6150 [USACO20FEB] Clock Tree S
我感觉我的智商收到了重创(
注意到一颗树,而我们需要在树上的边行走,于是考虑遍历 \(n\) 遍 dfs。
此时我们考虑如何 dfs。
::::info[提示]
每当 Bessie 走过一个边,父子节点同时加一。也就是说要改就父子一起改,父子之间的差是不变的。
题目求是否正确,参考 dfs,我们能想到什么做法?
::::
::::success[做法]
父子之差是固定的,想要拨到 \(12\),就需要孩子节点先到 \(12\),此时我们可以求出父亲节点的值,再去实现剩余孩子节点。再返回上一层继续求解。
::::info[如果你不懂]
dfs 最终会遍历到叶子节点,想让它变成 \(12\) 我们就需要按照上述的方法实现。当叶子节点完成后,这个父节点可以根据父子差求出来,此时它的孩子不能动了,于是可以将它作为叶子节点继续求解。
::::
此时我们将所有的节点求完,只剩下根节点,此时我们应该判断?
::::warning[一个可能的错误]
很明显如果根节点为 \(12\) 的话是正确的,但单纯统计 \(12\) 是不够的。
::::
::::success[正确做法]
模拟可得有一种走法是最后不走根节点,相当于少统计了一个 \(1\),反过来,也就是说,如果根节点的值为 \(1\),那么此方案也是可行的。
::::
为了方便实现,我们将值模 \(12\)。
::::success[代码]
/*
time : <DATETIME>
contest :
Problem :
Solution :
Code by 720872
*/
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<climits>
#include<bitset>
#define ll long long
#define ull unsigned long long
#define il inline
#define endl '\n'
#define y1 Y1
#define pii pair<int,int>
#define pli pair<ll, int>
#define pll pair<ll, ll>
#define _1 first
#define _2 second
#define mkp make_pair
#define pb push_back
#define debug cout << "debug" << endl;
#ifdef __unix__
#define gc getchar_unlocked
#else
#define gc _getchar_nolock
#endif
using namespace std;
inline ll read(){
int k = 0, f = 1, c = gc();
for (; !isdigit(c); c = gc()) if (c == '-') f = -1;
for (; isdigit(c); c = gc()) k = k * 10 + (c ^ 48);
return k * f;
}
//inline void put(ll x){
// if(x < 0) putchar('-'), x = -x;
// if(x < 10) putchar(x + '0');
// else put(x / 10), putchar(x % 10 + '0');
//}
const int N = 2505;
int n, a[N], c[N], ans;
vector<int> g[N];
void dfs(int x, int f){
for(int i = 0; i < g[x].size(); i++){
int y = g[x][i];
if(y == f) continue;
dfs(y, x);
a[x] = (a[x] - a[y] + 12) % 12;
}
}
signed main(){
// freopen(".in", "r0", stdin);
// freopen(".out", "w", stdout);
// ios::sync_with_stdio(false);
// cin.tie(0); cout.tie(0);
n = read();
for(int i = 1; i <= n; i++)
c[i] = read(), c[i] %= 12;
for(int i = 1; i <= n - 1; i++){
int x = read(), y = read();
g[x].pb(y), g[y].pb(x);
}
for(int i = 1; i <= n; i++){
memcpy(a, c, sizeof a);
dfs(i, 0);
if(a[i] == 1 || a[i] == 0)
ans++;
}
cout << ans;
return 0;
}
/*
*/
::::

浙公网安备 33010602011771号