前言
t
a
g
:
tag :
tag: 树形结构
构造
素数
染色
*1400
传送门 :
题意 :
给定一棵树,询问是否存在一种赋边权值方案,使得长度
≤
2
\le 2
≤2的路径,权值和是一个素数,如果不存在这种方案输出
−
1
-1
−1,否则输出这种方案
思路 :
首先需要知道一个结论 :
2 与 其 他 素 数 的 和 可 为 素 数 , 除 2 之 外 任 意 两 个 素 数 的 和 都 为 大 于 2 的 偶 数 即 合 数 2与其他素数的和可为素数,除2之外任意两个素数的和都为大于2的偶数即合数 2与其他素数的和可为素数,除2之外任意两个素数的和都为大于2的偶数即合数
则显然的,我们在 路 径 长 度 = 2 路径长度=2 路径长度=2的一边中总会存在一个 2 2 2
因此不难推断出,当一个节点度数为 3 3 3 时,不存在构造方案,因为总会存在 2 , 2 2,2 2,2这种路径
那么这颗树,显然就变成了一个链,我们类比于黑白染色的操作
找到一个入度为
1
1
1的点,然后跳着涂色即可
’
code :
vector<node> g[N];
int st[N];
int ans[N];
void dfs(int u,int col){
if(!st[u]){
st[u] = 1;
for(auto x : g[u]){
if(!st[x.to]){
ans[x.id] = col;
dfs(x.to,col^1);
}
}
}
}
void solve(){
int n;cin>>n;
for(int i=1;i<=n;i++) g[i].clear();
for(int i=1;i<=n;i++) st[i] = 0;
for(int i=1;i<n;i++){
int u,v;cin>>u>>v;
g[u].pb({v,i});
g[v].pb({u,i});
}
for(int i=1;i<=n;i++){
if(g[i].size() >= 3){
cout<<-1<<endl;
return;
}
}
int root = 0 ;
for(int i = 1;i<=n;i ++ )
if(g[i].size() == 1) root = i;
dfs(root,2);
for(int i=1;i<=n-1;i++) cout<<ans[i]<<" ";
cout<<endl;
}