【Atcoder】 [ARC156C] Tree and LCS

题目链接

Luogu方向
Atcoder方向

题目解法

手玩几个小数据之后可以猜测最小的最大相似度一定为1

考虑构造:每次找到2个叶子,交换权值,然后删掉(最后如果剩下一个点权值不变)
证明:
首先可以证明最大的相似度一定 > = 1 >=1 >=1
首先可以知道最大相似度一定是在极长的路径中(即无法再扩充的路径)
考虑 u , v u,v u,v 之间的路径

  1. 路径中没有 2 2 2 个点匹配
    那么每个点(可能除了根)一定和路径外的点匹配且交换了权值,那么这条路径中一定没有点的权值(可能除了根)与路径上其他点的编号相同,所以相似度最多为 1 1 1(即根无法匹配)
  2. 路径中有 2 2 2 个点匹配

令在 u − l c a u-lca ulca 的路径上匹配的点为 x x x,在 v − l c a v-lca vlca 的路径上匹配的点为 y y y
可以证明 x , y x,y x,y 一定不同时在 u − l c a u-lca ulca v − l c a v-lca vlca 的路径上,因为父亲一定比儿子晚删
所以可以有这样一张图:在这里插入图片描述
考虑在 u − x u-x ux 上的点 p p p,它匹配的点 q q q 有2种情况
3. q q q u − v u-v uv 的路径上,那么 q q q 一定在 v − y v-y vy
如果在 y − l c a y-lca ylca 上,那么 p p p x x x 早删, q q q y y y 晚删, x , y x,y x,y 同时删,矛盾
4. q q q 不在 u − v u-v uv 的路径上,不用考虑,没有影响

所以说 u − v u-v uv 的路径是类似关于 l c a lca lca 对称的
u − l c a u-lca ulca 的从下到上的点在 v − l c a v-lca vlca 上的对应点也是从下到上的
v − l c a v-lca vlca 的同理
所以该构造最小的最大相似度为1

#include <bits/stdc++.h>
using namespace std;
const int N(5100);
int n,deg[N],val[N]; 
int que[N],hh,tt=-1;
int e[N<<1],ne[N<<1],h[N],idx;
inline int read(){
	int FF=0,RR=1;
	char ch=getchar();
	for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;
	for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;
	return FF*RR;
}
void add(int a,int b){ e[idx]=b,ne[idx]=h[a],h[a]=idx++;}
int main(){
	n=read();
	memset(h,-1,sizeof(h));
	for(int i=1,x,y;i<n;i++) x=read(),y=read(),add(x,y),add(y,x),deg[x]++,deg[y]++;
	for(int i=1;i<=n;i++) if(deg[i]==1) que[++tt]=i;
	while(hh<=tt){
//		cout<<hh<<' '<<tt<<' '<<que[hh]<<'\n';
		if(hh==tt){ val[que[hh]]=que[hh];break;}
		int u=que[hh++],v=que[hh++];
		val[u]=v,val[v]=u; 
		for(int i=h[u];~i;i=ne[i]){
			deg[e[i]]--;
			if(deg[e[i]]==1) que[++tt]=e[i];
		}
		for(int i=h[v];~i;i=ne[i]){
			deg[e[i]]--;
			if(deg[e[i]]==1) que[++tt]=e[i];
		}
	}
	for(int i=1;i<=n;i++) printf("%d ",val[i]);
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值