加载中...

P6150 [USACO20FEB] Clock Tree S

我感觉我的智商收到了重创(

link

注意到一颗树,而我们需要在树上的边行走,于是考虑遍历 \(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;
}
/*
*/

::::

posted @ 2026-04-01 20:16  碎碎念的女巫  阅读(0)  评论(0)    收藏  举报