codeforces div2 Not Assigning 题解

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 ;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值