AT5759 ThREE 题解

AT5759 ThREE

sol

这个问题显然只有 \(\%3\) 的余数才有用,所以我们用 \(i \% 3\) 来替换 \(i\)

很容易发现,只要点对中存在一个 \(0\) ,那么肯定满足条件,所以先使用 \(1\) 和 \(2\) 来构造

要使得一个距离为 \(3\) 的点对符合要求,那么必须要让一个为 \(1\) ,一个为 \(2\),所以要使得所有权值相同的点不为 \(3\)。

由于 \(3\) 是单数,所以我们想到将树黑白染色,每一个点都与它相连的点颜色不同,所以将 黑白分别分配给 \(1,2\)

然后考虑加入 \(0\) 的情况

我们先默认 黑点数 \(≤\) 白点数

然后分两种情况

  1. 黑点数 \(≤ {n\over 3}\)

此时要将 \(0\) 来填充黑点,因为只要点对中出现一个 \(0\) 就必然合法,然后将 \(1,2\) 和剩下的 \(0\) 加入白点

  1. 黑点数 \(>{n\over 3}\) 可以先把 \(1,2\) 插入黑点,白点,然后将 \(0\) 填入剩下的黑点白点

code

#include<cstdio>
#include<iostream>
#include<vector>
using namespace std;
vector<int> v[3],c[3];
int N;
vector<int> e[200005];
int P[200005],col[200005];
inline int read(){
	int ret=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
	while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
	return ret*f;
}
void dfs(int x,int fa){
	col[x]=1-col[fa];
	c[col[x]+1].push_back(x);
	for(auto i:e[x]) if(i^fa) dfs(i,x);
}
int main(){
	freopen("AT5759.in","r",stdin);
	freopen("AT5759.out","w",stdout);
	N=read();
	for(int i=1,x,y;i<N;i++){
		x=read(),y=read();
		e[x].push_back(y);e[y].push_back(x);
	}
	dfs(1,0);
	for(int i=1;i<=N;i++) v[i%3].push_back(i);
	if(c[1].size()>c[2].size())swap(c[2],c[1]);
	int cnt0=0,cnt1=0,cnt2=0;
	if(c[1].size()<=N/3){
		for(auto i:c[1]) P[i]=v[0][cnt0++];
		for(auto i:c[2]){
			if(cnt0<v[0].size())P[i]=v[0][cnt0++];
			else if(cnt1<v[1].size())P[i]=v[1][cnt1++];
			else if(cnt2<v[2].size())P[i]=v[2][cnt2++];
		}
	}
	else {
		for(auto i:c[1]){
			if(cnt1<v[1].size())P[i]=v[1][cnt1++];
			else P[i]=v[0][cnt0++];
		}
		for(auto i:c[2]){
			if(cnt2<v[2].size())P[i]=v[2][cnt2++];
			else P[i]=v[0][cnt0++];
		}
	}
	for(int i=1;i<=N;i++)printf("%d ",P[i]);
	return 0;
}
上一篇:AGC040F Two Pieces


下一篇:C. Product of Three Numbers【1300 / 简单数论】