bzoj1005: [HNOI2008] Mingming trouble prufer sequence

https://www.lydsy.com/JudgeOnline/problem.php?id=1005

Given the points numbered 1 to N, and the final degree of some points, allowing a line to be connected between any two points, how many trees can be generated with the required degree?

Problem solution: prufer sequence, prufer sequence is a coding representation of an unrooted tree. For a numbered unrooted tree with n nodes, it corresponds to a unique string of prufer codes of length n-2.

The number of occurrences of a number in the prufer sequence is equal to the degree of the node with this number in the unrooted tree -1

Therefore, an undirected complete graph of n points has n^(n-2) spanning trees (a sequence of length n-2, and there are n ways to place each place)

The degree of n nodes is d1.d2.......dn, and the unrooted tree has a total of (n-2)!/(d1-1)!*(d2-1)!....*(dn -1)!, that is, the number of points is fixed (di-1), and the placement method is required to be different. The full arrangement is divided by the repeated placement of each point.

For this question, the remaining point left is n-2-di(di!=-1), a total of (n-2)!/(di-1)!*...*left!, and then each left has The points that can be placed in m (points with di==-1) are the methods in m^left

The final answer is (n-2)/(di-1)! . . . . *m^(left)

/**************************************************************
    Problem: 1005
    User: walfy
    Language: Java
    Result: Accepted
    Time:1432 ms
    Memory:20500 kb
****************************************************************/
 
import java.math.BigInteger;
import java.util.Scanner;
 
 
public  class Main {
 
    /**
     * @param args
     */
    static BigInteger [] fac = new BigInteger [1000+10];
    static void init()
    {
        fac[0] = BigInteger.ONE;
        for(int i=1;i<=1000;i++)
        {
            fac[i]=fac[i-1].multiply(BigInteger.valueOf(i));
        }
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner cin = new Scanner(System.in);
        init();
        int n = cin.nextInt ();
        int [] d = new  int [1000 + 10 ];
        int sum = 0, num = 0 ;
        BigInteger ans = fac[n-2];
        for(int i=1;i<=n;i++)
        {
            d[i] = cin.nextInt();
            if(d[i]!=-1)
            {
                sum += d[i]-1;
                ans =ans.divide(fac[d[i]-1 ]);
            }
            else num ++ ;
        }
        int left = n-2-sum;
        ans = ans.divide(fac[left]);
        ans = ans.multiply(BigInteger.valueOf(num).pow(left));
        System.out.println(ans);
    }
 
}
View Code

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325022606&siteId=291194637