Full Binary Tree(GCJ2014 round1A PB)

去年google code jam第一轮的B题,我没有想明白,也没有找到题解。没有办法,就去下载了大神的代码来看看。感觉差距好大,别人用十分钟不到就做出来了。题目的描述如下,我就不写翻译了,题意挺明了的。由于墙的原因,我还是把题目贴下面吧!

题目内容

A tree is a connected graph with no cycles.

A rooted tree is a tree in which one special vertex is called the root. If there is an edge between X and Y in a rooted tree, we say that Y is a child of X if X is closer to the root than Y (in other words, the shortest path from the root to X is shorter than the shortest path from the root to Y).

A full binary tree is a rooted tree where every node has either exactly 2 children or 0 children.

You are given a tree G with N nodes (numbered from 1 to N). You are allowed to delete some of the nodes. When a node is deleted, the edges connected to the deleted node are also deleted. Your task is to delete as few nodes as possible so that the remaining nodes form a full binary tree for some choice of the root from the remaining nodes.

Input

The first line of the input gives the number of test cases, T. T test cases follow. The first line of each test case contains a single integer N, the number of nodes in the tree. The following N-1 lines each one will contain two space-separated integers: Xi Yi, indicating that G contains an undirected edge between Xi and Yi.

Output

For each test case, output one line containing “Case #x: y”, where x is the test case number (starting from 1) and y is the minimum number of nodes to delete from G to make a full binary tree.

Limits

1 ≤ T ≤ 100.

1 ≤ Xi, Yi ≤ N

Each test case will form a valid connected tree.

Small dataset

2 ≤ N ≤ 15.

Large dataset

2 ≤ N ≤ 1000.

Sample

Input

Output

3

3

2 1

1 3

7

4 5

4 2

1 2

3 1

6 4

3 7

4

1 2

2 3

3 4

Case #1: 0

Case #2: 2

Case #3: 1

In the first case, G is already a full binary tree (if we consider node 1 as the root), so we don’t need to do anything.

In the second case, we may delete nodes 3 and 7; then 2 can be the root of a full binary tree.

In the third case, we may delete node 1; then 3 will become the root of a full binary tree (we could also have deleted node 4; then we could have made 2 the root).

题意就是给你很多对点,每对点之间有无向边。输入保证这个图是相连的,不是森林。题目要求你去掉一些点,使这个图成为完全二叉树。完全二叉树的是指任意节点的子节点数目为0或2。需要注意的是点对的父子关系不是确定的,这也是题目的难度所在。

我思考这个问题的时候主要是卡在了树的结构上。题目保证了没有孤立的点集,所以思考这个问题的第一步就是忘掉什么二叉树,把这个问题的输入看做是一个无向图,也不要管什么边上的父子关系。一个非常明确是结论是:对于一个连同的无向图,以任意节点为根都可以构造出一棵树,不考虑兄弟节点的顺序的话,这棵树是唯一的。当然这棵树很可能不是二叉树。

然后这个问题的思路就清晰了,求解以每个顶点为根的树形成二叉树的最小代价。然后找到最小值输出即可。求最小代价的原理就看注释吧!这下边是别人的代码,知道逻辑代码还是容易看懂的。

#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
vector<int>E[1010];
int n, Res, D[1010];      //题目的关键点在于无向五环图,题目的图没有孤立点
void DFS(int a, int par){ //任意形式的摆放都可以保证树的结构正确,不过不能保证是二叉树
    int i, cnt = 0;         //子节点多于两个的就必须选择删减代价最小的两个子树,把其余子树删除掉
    D[a] = 1;               //字节点少于两个的顶点的子节点全部删除掉
    for (i = 0; i < E[a].size(); i++){
        if (E[a][i] != par){
            DFS(E[a][i], a);
            cnt++;
        }
    }
    if (cnt <= 1)return;
    int M1 = 0, M2 = 0;
    for (i = 0; i < E[a].size(); i++){
        if (E[a][i] != par){
            if (M1 < D[E[a][i]]){
                M2 = M1; M1 = D[E[a][i]]; //
            }
            else if (M2 < D[E[a][i]]){
                M2 = D[E[a][i]];
            }
        }
    }
    D[a] = M1 + M2 + 1;
}    //
void Do(int a){
    int i;
    DFS(a, -1);
    if (Res > n - D[a]) Res = n - D[a];
}
int main()
{
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    int i, TC, T, a, b;
    scanf("%d", &TC);
    for (T = 1; T <= TC; T++){
        printf("Case #%d: ", T);
        scanf("%d", &n);
        for (i = 1; i < n; i++){
            scanf("%d%d", &a, &b);
            E[a].push_back(b);
            E[b].push_back(a);
        }
        Res = n;
        for (i = 1; i <= n; i++){
            Do(i);
        }
        printf("%d\n", Res);
        for (i = 1; i <= n; i++)E[i].clear();
    }
}
时间: 2024-10-07 01:30:47

Full Binary Tree(GCJ2014 round1A PB)的相关文章

2017浙江省赛 H - Binary Tree Restoring ZOJ - 3965

地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3965 题目: iven two depth-first-search (DFS) sequences of a binary tree, can you find a binary tree which satisfies both of the DFS sequences? Recall that a binary tree is a tree in which

Maximum Depth of Binary Tree

这道题为简单题 题目: Given a binary tree, find its maximum depth.The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. 思路: 我是用递归做的,当然也可以用深搜和广搜,递归的话就是比较左右子树的深度然后返回 代码: 1 # Definition for a binary tre

226反转二叉树 Invert Binary Tree

Invert a binary tree. 4 / 2 7 / \ / 1 3 6 9 to 4 / 7 2 / \ / 9 6 3 1 Trivia:This problem was inspired by this original tweet by Max Howell: Google: 90% of our engineers use the software you wrote (Homebrew), but you can't invert a binary tree on a wh

[leetcode] 104. Maximum Depth of Binary Tree

Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. 递归遍历 左子树 和 右子树 一刷: public int maxDepth(TreeNode root) { if(root == null){ return 0; } int

LeetCode 145 Binary Tree Postorder Traversal(二叉树的后续遍历)+(二叉树、迭代)

翻译 给定一个二叉树,返回其后续遍历的节点的值. 例如: 给定二叉树为 {1, #, 2, 3} 1 2 / 3 返回 [3, 2, 1] 备注:用递归是微不足道的,你可以用迭代来完成它吗? 原文 Given a binary tree, return the postorder traversal of its nodes' values. For example: Given binary tree {1,#,2,3}, 1 2 / 3 return [3,2,1]. Note: Recur

LeetCode Binary Tree Inorder Traversal

LeetCode解题之Binary Tree Inorder Traversal 原题 不用递归来实现树的中序遍历. 注意点: 无 例子: 输入: {1,#,2,3} 1 2 / 3 输出: [1,3,2] 解题思路 通过栈来实现,从根节点开始,不断寻找左节点,并把这些节点依次压入栈内,只有在该节点没有左节点或者它的左子树都已经遍历完成后,它才会从栈内弹出,这时候访问该节点,并它的右节点当做新的根节点一样不断遍历. AC源码 # Definition for a binary tree node

Java [Leetcode 107]Binary Tree Level Order Traversal II

题目描述: Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root). For example:Given binary tree {3,9,20,#,#,15,7}, 3 / 9 20 / 15 7 return its bottom-up level order

Lowest Common Ancestor of a Binary Tree

题目连接 https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/ Common Ancestor of a Binary Tree Description Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According to the definition of LCA on

Invert Binary Tree

package cn.edu.xidian.sselab; /** * title:Invert Binary Tree * content: * nvert a binary tree.  *     4 *   /   \ *  2     7 * / \   / \ *1   3 6   9 *to *     4 *   /   \ *  7     2 * / \   / \ *9   6 3   1 */public class InvertBinaryTree { /**