Live2D

AGC027 Grafting 题解

link

Solution

首先可以先判断同构情况。

然后考虑枚举两棵树的根,你可以枚举A的需要换的叶子当A、B根,因此你还需要枚举换到哪里,然后你就可以知道一个点该不该换,就可以知道答案。但是你还需要判断是否合法,你发现A中叶子比父亲先换,B中叶子比父亲后换,因此我们可以连边跑 topo 来验证是否有环。

复杂度 \(\Theta(Tn^3)\)

Code

#include <bits/stdc++.h>
using namespace std;

#define Int register int
#define MAXN 55

template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
template <typename T> inline void chkmax (T &a,T b){a = max (a,b);}
template <typename T> inline void chkmin (T &a,T b){a = min (a,b);}

int T,n;
vector <int> g[2][MAXN],t[MAXN];

int par[2][MAXN];
void dfs (int u,int k,int fa){
	par[k][u] = fa;
	for (Int v : g[k][u]) if (v ^ fa) dfs (v,k,u);
}

int deg[MAXN],sig[MAXN];
bool checkit (int u){return par[0][u] != par[1][u];}
void link (int u,int v){t[u].push_back (v),deg[v] ++;}

void Work (){
	read (n);
	for (Int i = 1;i <= n;++ i) g[0][i].clear(),g[1][i].clear(),sig[i] = 0;
	for (Int i = 2,u,v;i <= n;++ i) read (u,v),sig[u] ++,sig[v] ++,g[0][u].push_back (v),g[0][v].push_back (u);
	for (Int i = 2,u,v;i <= n;++ i) read (u,v),g[1][u].push_back (v),g[1][v].push_back (u);
	int ans = 1e9;bool flag = 0;
	dfs (1,0,0),dfs (1,1,0);
	for (Int i = 1;i <= n;++ i) flag |= (par[0][i] != par[1][i]);
	if (!flag){puts ("0");return ;}
	for (Int rt1 = 1;rt1 <= n;++ rt1) if (sig[rt1] == 1){
		dfs (rt1,1,0);
		for (Int rt2 = 1;rt2 <= n;++ rt2) if (rt1 != rt2){
			dfs (rt2,0,0),par[0][rt2] = rt1,par[0][rt1] = 0;
			int sum = 0;
			for (Int i = 1;i <= n;++ i) t[i].clear(),deg[i] = 0;
			for (Int i = 1;i <= n;++ i) if (checkit (i)) sum ++;
			bool tag = 1;
			for (Int i = 1;i <= n;++ i) if (!checkit (i) && checkit (par[0][i])){tag = 0;break;}
			if (!tag) continue;
			for (Int i = 1;i <= n;++ i){
				if (checkit (i) && checkit (par[1][i])) link (par[1][i],i);
				if (checkit (i) && checkit (par[0][i])) link (i,par[0][i]);
			}
			queue <int> q;
			for (Int i = 1;i <= n;++ i) if (!deg[i]) q.push (i);
			while (!q.empty()){
				int u = q.front();q.pop ();
				for (Int v : t[u]) if (!-- deg[v]) q.push (v); 
			}
			bool flg = 0;
			for (Int i = 1;i <= n;++ i) flg |= deg[i];
			if (!flg) chkmin (ans,sum + 1);
		}
	}
	write (ans == 1e9 ? -1 : ans),putchar ('\n');
}

signed main(){
	read (T);
	while (T --> 0) Work ();
	return 0;
}
posted @ 2022-02-05 19:47  Dark_Romance  阅读(33)  评论(1编辑  收藏  举报