[AGC014E] Blue and Red Tree

考虑倒推,最后一条被替换的边,一定本身就是红树上的边,然后这个时候这条边两边的联通块一定已经处理好了。
然后我们不难发现,所有连边操作本质都可以归为重边操作,并且连通性不变。
启发式合并即可。

#include<bits/stdc++.h>
#define RG register
#define LL long long
#define U(x,y,z) for(RG int x=y;x<=z;++x)
#define D(x,y,z) for(RG int x=y;x>=z;--x)
using namespace std;
template <typename T> void read(T &n){ bool f = 1; char ch = getchar(); n = 0; for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = 0; for (; isdigit(ch); ch = getchar()) n = (n << 1) + (n << 3) + (ch ^ 48); if (f == 0) n = -n;}
inline char Getchar(){ char ch; for (ch = getchar(); !isalpha(ch); ch = getchar()); return ch;}
template <typename T> inline void write(T n){ char ch[60]; bool f = 1; int cnt = 0; if (n < 0) f = 0, n = -n; do{ch[++cnt] = char(n % 10 + 48); n /= 10; }while(n); if (f == 0) putchar('-'); for (; cnt; cnt--) putchar(ch[cnt]);}
template <typename T> inline void writeln(T n){write(n); putchar('\n');}
template <typename T> inline void writesp(T n){write(n); putchar(' ');}
template <typename T> inline void chkmin(T &x, T y){x = x < y ? x : y;}
template <typename T> inline void chkmax(T &x, T y){x = x > y ? x : y;}
template <typename T> inline T Min(T x, T y){return x < y ? x : y;}
template <typename T> inline T Max(T x, T y){return x > y ? x : y;}
inline void readstr(string &s) { s = ""; static char c = getchar(); while (isspace(c)) c = getchar(); while (!isspace(c)) s = s + c, c = getchar();}
inline void FO(string s){freopen((s + ".in").c_str(), "r", stdin); freopen((s + ".out").c_str(), "w", stdout);}
#define N 100010
multiset<int> e[N];
#define pii pair <int, int>
#define mp make_pair
#define fi first
#define se second
map<pii, int> hsh;
int n;
queue< pii > q;
inline void aedge(int x, int y){if (x > y) swap(x, y);if (x == y) return ; if (hsh[mp(x, y)]) q.push(mp(x, y)); hsh[mp(x, y)] = 1; e[x].insert(y); e[y].insert(x);}
int main(){
	//FO("");
	read(n);
	U(i, 2, n){
		int x, y;
		read(x), read(y);
		aedge(x, y);
	}
	U(i, 2, n){
		int x, y;
		read(x), read(y);
		aedge(x, y);
	}
	U(i, 1, n - 1){
//		cout << q.size() << endl;
		if (q.empty()){
			puts("NO");
			return 0;
		}
		pii Q = q.front(); q.pop(); if (!hsh[Q]){i--; continue ;}
		int u = Q.fi, v = Q.se;
		if (e[u].size() < e[v].size()) swap(u, v);
		for (auto to: e[v]){hsh[mp(min(v, to), max(to, v))] = 0; aedge(to, u); e[to].erase(e[to].find(v));};
	}
	puts("YES");
	return 0;
}
posted @ 2022-10-26 20:57  Southern_Way  阅读(15)  评论(0)    收藏  举报