codeforces div2 Not Assigning 题解
原题链接
/*
题意:构造一棵素数树。素数树定义如下:
这颗树中任意一条边 or 任意两条边 权重之和为素数,每条边的权重自己分配。
输入;t个样例 , n个点 ,(n-1)边。分别是两点连接第一条边,两点连接第二条边 ……
输出:如果不能构造素数树,那么输出-1,;如果可以构造,输出每一条边的边权。
分析1:三个任意素数,其中任意两个素数之和不可能全部为素数。
比如:2 , 3 ,5 三个素数,2 + 3 是素数 ,2 + 5 是素数 ,但 3 + 5 不是素数 ,证明略。
分析2:这棵树的其中一个节点的度如果大于等于3 ,那么就不能构造素数树,证明见分析1.
结论:这颗素数树必须为一条链状,否则不满足题意。
*/
#include<bits/stdc++.h>
using namespace std ;
#define int long long
const int N = 1e5 + 99 ;
typedef pair < int ,int > PII ;
vector < PII > v[N] ; // 用来构建这颗树
int deg[N] ; // 计算这颗树每一个点的度
int n ;
int ans[N] ;
void init(){
for(int i = 1 ; i <= n ; i ++ ){
deg[i] = 0 ;
v[i].clear() ;
}
}
void dfs(int u , int fa , int idx ){
for(auto p : v[u]){
int s = p.first , id = p.second ; // 分别表示根节点和边
if(s == fa){
continue ;
}
if(idx % 2 == 0){
ans[id] = 2 ; // 这个是对每一条边赋值,两个素数相加依然为素数即可,并不唯一。
}else{
ans[id] = 3 ;
}
dfs(s , u , ++ idx ) ; // 节点 s 继续向下搜索 , 父亲节点为 u 。
}
}
void solve(){
for(int i = 1 ; i <= n ; i ++){
if(deg[i] >= 3){
cout << "-1" << endl ;
return ;
}
}
for(int i =1 ; i <= n ; i ++){
if(deg[i] == 1){ // 如果它的度等于1 , 就把这个点当做根节点。
dfs(i , 0 , 0 ) ;
break ;
}
}
for(int i = 1 ; i < n ; i ++ ){
cout << ans[i] << " " ;
}
cout << endl;
}
signed main(){
ios::sync_with_stdio(false) ;
int t ;
cin >> t ;
while(t --){
cin >> n ;
init() ; // 对上棵树的度和树进行清空操作,
for(int i = 1 ; i < n ; i ++ ){
int a , b ;
cin >> a >> b ;
deg[a] ++ ;
deg[b] ++ ;
v[a].push_back({b,i}) ;
v[b].push_back({a,i}) ;
}
solve() ; // 解决这个题的函数
}
return 0 ;
}