ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【题解】CF650E-Clockwork Bomb

2022-05-17 22:31:07  阅读:177  来源: 互联网

标签:pb Bomb 删除 int 题解 dfs Clockwork fa rp


给定两棵树 \(A,B\),每次先删除 \(A\) 一条边,再加入 \(A\) 一条边,过程中不能成环,现在构造一个方案用最少次操作将 \(A\) 变成 \(B\)。

显然两棵树中都存在的边可以不用删,我们将这些边留下,将每个连通块缩成一个点。

那么我们得到两颗大小相同的新树,且不存在一条边在两棵树内都出现。

考虑从叶子开始删除,每次删除一个叶子与其父节点的边,然后连上需要还原的 \(B\) 边。操作完成后叶子的父边算是还原了,就可以直接将叶子删除。由于每次删除都是分裂出一个节点,再把这个节点接回去,所以是正确的。

时间复杂度 \(\mathcal{O}(N)\)。

#define N 500005
struct Tree{
	vector<int>e[N]; int fa[N];
	void dfs(int x,int f){fa[x] = f; go(y, e[x])if(y != f)dfs(y, x);}
}A, B;
int n, fa[N];
int get(int x){return fa[x] == x ? x : fa[x] = get(fa[x]);}
struct node{int x, y, a, b;};
vector<node>ed;
void dfs(int x,int f){
	go(y, A.e[x])if(y != f){
		dfs(y, x);
		if(fa[y] != fa[x])ed.pb(node{x, y, fa[y], B.fa[fa[y]]});
	}
}
int main() {
	read(n);
	rp(i, n - 1){
		int x, y; read(x, y);
		A.e[x].pb(y), A.e[y].pb(x);
	}
	rp(i, n - 1){
		int x, y; read(x, y);
		B.e[x].pb(y), B.e[y].pb(x);
	}
	A.dfs(1, 0), B.dfs(1, 0);
	rp(i, n)fa[i] = i;
	rep(x, 2, n){
		int y = B.fa[x];
		if(A.fa[x] == y || A.fa[y] == x)fa[x] = y;
	}
	rp(i, n)get(i);
	dfs(1, 0);
	printf("%d\n", si(ed));
	go(x, ed)printf("%d %d %d %d\n", x.x, x.y, x.a, x.b);
	return 0;
}

标签:pb,Bomb,删除,int,题解,dfs,Clockwork,fa,rp
来源: https://www.cnblogs.com/7KByte/p/16282669.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有