Offer收割赛25 #1567 偶树分割

时间限制: 10000ms
单点时限: 1000ms
内存限制: 256MB

描述

如果一棵树节点数目是偶数,那么就称这棵树是偶树。给定一棵N个节点的偶树(编号1~N),小Hi想知道他最多可以同时切断多少条边,使得剩下的森林中每一个联通分量都是一棵偶树。

例如如下的偶树:

      1   
   / | | \
  2  3 4  5
  |
  6

可以切断1-2之间边使得剩下的每个联通分量都是偶树。

输入

第一行包含一个偶数N。  

以下N-1行每行包含两个整数a和b,表示a和b之间有一条边。  

对于30%的数据,1 ≤ N ≤ 20  

对于100%的数据, 1 ≤ N ≤ 100000

输出

输出最多可以切断的边数。

样例输入
6  
1 2  
3 1  
4 1  
1 5  
6 2
样例输出
1
代码出自:

http://hihocoder.com/user/1731

思路:

统计奇子树的个数 dfs就行

ps:

有时间补上详细的分析。

代码:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
//这题的问题可以转化为统计奇数子树的个数
public class Main{
static List<Integer>[] edges;
static boolean[] use;
static int ans;
public static  void main(String[] args){
Scanner in = new Scanner(System.in);
int n = in.nextInt();
edges = new List[n];
for(int i=0;i < n;i++) edges[i] = new ArrayList<>();
for(int i=0;i < n-1;i++){
int a = in.nextInt()-1;
int b = in.nextInt()-1;
edges[a].add(b);
edges[b].add(a);
}
use = new boolean[n];
//从0节点开始深度优先访问
dfs(0);
System.out.println(ans);
}
//深度优先
static int dfs(int node){
//状态设置为访问,
use[node] = true;
int sum  =1;
for(int child:edges[node]){
if(!use[child]){
int num = dfs(child);
//统计拥有奇数个子孙的树个数
if(num % 2 == 0) ans ++;
sum += num;
}
}
//状态设置为退出
use[node] = false;
//返回的是子树节点的个数
return sum;
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值