2023年浙大城市学院新生程序设计竞赛(同步赛)G

登录---专业IT笔试面试备考平台_牛客网

题意

思路

首先想法非常单一,一定是去枚举操作点,然后看它染白和不染的价值差值

也就是说,把一个黑色结点染白之后,对哪些结点的价值会影响

不难想象其实就是操作结点的子树和该点连通的黑色连通块的所有结点,对这些结点会有影响

那么差值其实就是黑色连通块大小 * 操作点到最近的白色祖先的距离

黑色连通块容易用树形dp求,然后就是操作点到最近白色祖先距离怎么求

dfs即可,记录上次的白色结点是什么即可

cpp 复制代码
#include <bits/stdc++.h>
 
#define int long long
 
constexpr int N = 2e5 + 10;
 
std::vector<int> adj[N];
 
int n;
int a[N];
int lst[N];
int sz[N], dep[N], F[N][33];
int dp[N];
 
void dfs(int u, int fa) {
	sz[u] = 1;
	dep[u] = dep[fa] + 1;
	F[u][0] = fa;
	for (int i = 1; i <= 30; i++) {
		F[u][i] = F[F[u][i - 1]][i - 1];
	}
	for (auto v : adj[u]) {
		if (v == fa) continue;
		dfs(v, u);
		sz[u] += sz[v];
	}
}
void dfs2(int u, int fa) {
	if (a[u] == 1) dp[u] = 1;
	for (auto v : adj[u]) {
		if (v == fa) continue;
		dfs2(v, u);
		if (a[v] == 1) {
			dp[u] += dp[v];
		}
	}
}
void dfs3(int u, int fa, int last) {
	lst[u] = last;
	for (auto v : adj[u]) {
		if (v == fa) continue;
		int clst = 0;
		if (a[v]) {
			clst = last;
		}else {
			clst = v;
		}
		dfs3(v, u, clst); 
	}
}
int lca(int u, int v) {
	if (dep[u] < dep[v]) {
		std::swap(u, v);
	}
	for (int j = 30; j >= 0; j --) {
		if (dep[F[u][j]] >= dep[v]) {
			u = F[u][j];
		} 
	}
	if (u == v) return u;
	for (int j = 30; j >= 0; j --) {
		if (F[u][j] != F[v][j]) {
			u = F[u][j];
			v = F[v][j];
		}
	}
	return F[u][0];
}
int dis(int u, int v) {
	return dep[u] + dep[v] - 2 * dep[lca(u, v)];
}
 
void solve() {
	std::cin >> n;
	for (int i = 1; i <= n; i ++) {
		std::cin >> a[i];
	}
	for (int i = 1; i <= n - 1; i ++) {
		int u, v;
		std::cin >> u >> v;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}
	dfs(1, 0);
	dfs3(1, 0, 1);
	for (int i = 1; i <= n; i ++) {
		lst[i] = dis(i, lst[i]);
	}
	dfs2(1, 0);
	int cur = 0;
	for (int u = 1; u <= n; u ++) {
		if (a[u] == 1) {
			cur += lst[u];
		}
	}
	int ans = cur;
	for (int u = 1; u <= n; u ++) {
		if (!a[u]) continue;
		int res = cur;
		res -= dp[u] * lst[u];
		ans = std::min(ans, res);
	}
	std::cout << ans << "\n";
}
signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	
	int t = 1;
	while(t --) {
		solve();
	}
	return 0;
} 
相关推荐
顶呱呱程序7 分钟前
2-143 基于matlab-GUI的脉冲响应不变法实现音频滤波功能
算法·matlab·音视频·matlab-gui·音频滤波·脉冲响应不变法
Tianyanxiao28 分钟前
如何利用探商宝精准营销,抓住行业机遇——以AI技术与大数据推动企业信息精准筛选
大数据·人工智能·科技·数据分析·深度优先·零售
爱吃生蚝的于勒29 分钟前
深入学习指针(5)!!!!!!!!!!!!!!!
c语言·开发语言·数据结构·学习·计算机网络·算法
羊小猪~~32 分钟前
数据结构C语言描述2(图文结合)--有头单链表,无头单链表(两种方法),链表反转、有序链表构建、排序等操作,考研可看
c语言·数据结构·c++·考研·算法·链表·visual studio
王哈哈^_^1 小时前
【数据集】【YOLO】【VOC】目标检测数据集,查找数据集,yolo目标检测算法详细实战训练步骤!
人工智能·深度学习·算法·yolo·目标检测·计算机视觉·pyqt
星沁城1 小时前
240. 搜索二维矩阵 II
java·线性代数·算法·leetcode·矩阵
脉牛杂德1 小时前
多项式加法——C语言
数据结构·c++·算法
legend_jz1 小时前
STL--哈希
c++·算法·哈希算法
kingmax542120081 小时前
初三数学,最优解问题
算法
一直学习永不止步2 小时前
LeetCode题练习与总结:赎金信--383
java·数据结构·算法·leetcode·字符串·哈希表·计数