dsu on tree 模板

dsu on tree模板运用

例题以及代码:

U41492 树上数颜色 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

记录详情 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

Lomsat gelral - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

记录详情 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

struct DsuOnTree {
	int n, dfn = 0;
	vector<int> sz, big, L, R, Node;
	vector<vector<int>> g;

	//根据题目要求修改
	i64 Max = 0, now = 0;
	vector<i64> ans, cnt, col;

	DsuOnTree(int n): n(n), sz(n + 1), big(n + 1), L(n + 1), R(n + 1), Node(n + 1) {
		g.resize(n + 1);

		ans.resize(n + 1);
		col.resize(n + 1);
		cnt.resize(n + 1);
	}

	void add(int u, int v) {
		g[u].emplace_back(v);
		g[v].emplace_back(u);
	}

	void add(int u) {
		//计算贡献

	}

	void del(int u) {
		//删除贡献

	}

	i64 getAns() {
		return now;
	}

	void dfs0(int u, int fa) {
		L[u] = ++dfn;
		Node[dfn] = u;
		sz[u] = 1;
		for (int v : g[u])
			if (v != fa) {
				dfs0(v, u);
				sz[u] += sz[v];
				if (!big[u] || sz[big[u]] < sz[v])
					big[u] = v;
			}
		R[u] = dfn;
	}

	void dfs1(int u, int fa, bool keep) {
		// 计算轻儿子的答案
		for (int v : g[u])
			if (v != fa && v != big[u]) {
				dfs1(v, u, false);
			}
		// 计算重儿子答案并保留计算过程中的数据(用于继承)
		if (big[u]) {
			dfs1(big[u], u, true);
		}
		for (int v : g[u])
			if (v != fa && v != big[u]) {
				// 子树结点的 DFS 序构成一段连续区间,可以直接遍历
				for (int i = L[v]; i <= R[v]; i++) {
					add(Node[i]);
				}
			}
		add(u);
		ans[u] = getAns();
		if (keep == false) {
			for (int i = L[u]; i <= R[u]; i++) {
				del(Node[i]);
			}
		}
	}
};
posted @ 2024-07-28 20:26  Ke_scholar  阅读(21)  评论(0编辑  收藏  举报