首页 > 专题系列 > Java解POJ > POJ 2367 Genealogical tree [解题报告] Java
2013
11-11

POJ 2367 Genealogical tree [解题报告] Java

Genealogical tree

问题描述 :

The system of Martians’ blood relations is confusing enough. Actually, Martians bud when they want and where they want. They gather together in different groups, so that a Martian can have one parent as well as ten. Nobody will be surprised by a hundred of children. Martians have got used to this and their style of life seems to them natural.

And in the Planetary Council the confusing genealogical system leads to some embarrassment. There meet the worthiest of Martians, and therefore in order to offend nobody in all of the discussions it is used first to give the floor to the old Martians, than to the younger ones and only than to the most young childless assessors. However, the maintenance of this order really is not a trivial task. Not always Martian knows all of his parents (and there’s nothing to tell about his grandparents!). But if by a mistake first speak a grandson and only than his young appearing great-grandfather, this is a real scandal.

Your task is to write a program, which would define once and for all, an order that would guarantee that every member of the Council takes the floor earlier than each of his descendants.

输入:

The first line of the standard input contains an only number N, 1 <= N <= 100 — a number of members of the Martian Planetary Council. According to the centuries-old tradition members of the Council are enumerated with the natural numbers from 1 up to N. Further, there are exactly N lines, moreover, the I-th line contains a list of I-th member's children. The list of children is a sequence of serial numbers of children in a arbitrary order separated by spaces. The list of children may be empty. The list (even if it is empty) ends with 0.

输出:

The standard output should contain in its only line a sequence of speakers’ numbers, separated by spaces. If several sequences satisfy the conditions of the problem, you are to write to the standard output any of them. At least one such sequence always exists.

样例输入:

5
0
4 5 1 0
1 0
5 3 0
3 0

样例输出:

2 4 5 3 1

解题代码:

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * 
 * Accepted. BigInteger is used here.
 * 
 * 
 */
public class Main {

     public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);

        int n = cin.nextInt();

        int[][] a = new int[n + 1][n + 1];
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                a[i][j] = 0;
            }
        }

        int[] depth = new int[n + 1];
        for (int i = 0; i <= n; i++) {
            depth[i] = 0;
        }

        for (int i = 1; i <= n; i++) {
            while (true) {
                int k = cin.nextInt();

                if (k == 0) {
                    break;
                }

                a[i][k] = 1;
                depth[k]++;
            }
        }

        List list = new ArrayList();

        boolean[] picked = new boolean[n + 1];
        for (int i = 1; i <= n; i++) {
            picked[i] = false;
        }

        while (list.size() < n) {

            for (int i = 1; i<= n; i++) {
                if (picked[i] == false && depth[i] == 0) {
                    list.add(i);
                    picked[i] = true;
                    

                    for (int j = 1; j<= n; j++) {
                        
                        if (picked[j] == false && a[i][j] == 1) {
                            depth[j]--;
                        }
                    }
                    
                    break;
                }
            }
        }
        
        for (int i = 0; i < list.size(); i++) {
            
            if (i > 0) {
                System.out.print(" ");
            }
            System.out.print(list.get(i));
        }
        
        System.out.println();
    }


}

  1. 一开始就规定不相邻节点颜色相同,可能得不到最优解。我想个类似的算法,也不确定是否总能得到最优解:先着一个点,随机挑一个相邻点,着第二色,继续随机选一个点,但必须至少有一个边和已着点相邻,着上不同色,当然尽量不增加新色,直到完成。我还找不到反例验证他的错误。。希望LZ也帮想想, 有想法欢迎来邮件。谢谢

  2. 其实国内大部分公司对算法都不够重视。特别是中小型公司老板根本都不懂技术,也不懂什么是算法,从而也不要求程序员懂什么算法,做程序从来不考虑性能问题,只要页面能显示出来就是好程序,这是国内的现状,很无奈。