Problem:
Score : 800 points

Problem Statement

There is a tree with N vertices. The vertices are numbered 1 through N. The i-th edge (1 \leq i \leq N - 1) connects Vertex x_i and y_i. For vertices v and w (1 \leq v, w \leq N), we will define the distance between v and w d(v, w) as "the number of edges contained in the path v-w".

A squirrel lives in each vertex of the tree. They are planning to move, as follows. First, they will freely choose a permutation of (1, 2, ..., N), p = (p_1, p_2, ..., p_N). Then, for each 1 \leq i \leq N, the squirrel that lived in Vertex i will move to Vertex p_i.

Since they like long travels, they have decided to maximize the total distance they traveled during the process. That is, they will choose p so that d(1, p_1) + d(2, p_2) + ... + d(N, p_N) will be maximized. How many such ways are there to choose p, modulo 10^9 + 7?

Constraints

2 \leq N \leq 5,000

1 \leq x_i, y_i \leq N

The input graph is a tree.

Input

Input is given from Standard Input in the following format:

N
x_1 y_1
x_2 y_2
:
x_{N - 1} y_{N - 1}

Output

Print the number of the ways to choose p so that the condition is satisfied, modulo 10^9 + 7.

Sample Input 1

3
1 2
2 3

Sample Output 1

3

The maximum possible distance traveled by squirrels is 4.
There are three choices of p that achieve it, as follows:

(2, 3, 1)

(3, 1, 2)

(3, 2, 1)

Sample Input 2

4
1 2
1 3
1 4

Sample Output 2

11

The maximum possible distance traveled by squirrels is 6.
For example, p = (2, 1, 4, 3) achieves it.

Sample Input 3

6
1 2
1 3
1 4
2 5
2 6

Sample Output 3

36

Sample Input 4

7
1 2
6 3
4 5
1 7
1 5
2 3

Sample Output 4

396

Solution in Rust (1.15.1) (judge verdict: Accepted)

use std::io::*;
use std::str::FromStr;

fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

// a x + b y = gcd(a, b)
fn extgcd(a: i64, b: i64, x: &mut i64, y: &mut i64) -> i64 {
    let mut g = a;
    *x = 1;
    *y = 0;
    if b != 0 {
        g = extgcd(b, a % b, y, x);
        *y -= (a / b) * *x;
    }
    g
}

fn inv_mod(a: i64, modulo: i64) -> i64 {
    let (mut x, mut y) = (0, 0);
    if extgcd(a, modulo, &mut x, &mut y) == 1 {
        return (x + modulo) % modulo;
    }
    0
}

const MOD: i64 = 1e+9 as i64 + 7;
static mut FACTORIAL: [i64; 10000] = [0; 10000];
fn fact(n: usize) -> i64 {
    unsafe { FACTORIAL[n] }
}
fn combi(n: usize, m: usize) -> i64 {
    if n < m { return 0; }
    unsafe {
        FACTORIAL[n] * inv_mod(FACTORIAL[m] * FACTORIAL[n - m] % MOD, MOD) % MOD
    }
}

fn solve(n: usize, vs: &Vec<usize>) -> i64 {
    let mut dp = vec![0; n + 1];
    dp[0] = 1;
    for m in vs {
        let mut ndp = vec![0; n + 1];
        for j in 0..m+1 {
            let cnt = combi(*m, j) * fact(*m) % MOD * inv_mod(fact(m - j), MOD) % MOD;
            for i in 0..n+1 {
                if i + j > n { break; }
                ndp[i + j] = (ndp[i + j] + cnt * dp[i]) % MOD;
            }
        }
        dp = ndp;
    }
    let mut ans = 0;
    let mut sign = 1;
    for i in 0..n {
        ans = (ans + dp[i] * fact(n - i) % MOD * sign + MOD) % MOD;
        sign *= -1;
        // println!("{}", dp[i]);
    }
    ans
}

type Weight = i32;
#[derive(Clone, Debug)]
struct Edge {
    index: usize,
    src: usize,
    dest: usize,
    weight: Weight,
}
impl Edge {
    fn new(index: usize, src: usize, dest: usize, weight: Weight) -> Edge {
        Edge {
            index: index,
            src: src,
            dest: dest,
            weight: weight,
        }
    }
}
type Edges = Vec<Edge>;
type Graph = Vec<Edges>;
fn graph_new(n: usize) -> Graph {
    vec![vec![]; n]
}
fn add_bi_edge(graph: &mut Graph, index: &mut usize, src: usize, dest: usize, weight: Weight) {
    graph[src].push(Edge::new(*index, src, dest, weight));
    graph[dest].push(Edge::new(*index, dest, src, weight));
    *index += 1;
}

fn dfs(g: &Graph, from: usize, parent: usize) -> usize {
    let mut ret = 1;
    for edge in g[from].iter() {
        if edge.dest == parent { continue; }
        ret += dfs(g, edge.dest, from);
    }
    ret
}

fn main() {
    unsafe {
        FACTORIAL[0] = 1;
        for i in 1..10000 {
            FACTORIAL[i] = (FACTORIAL[i - 1] * i as i64) % MOD;
        }
    }
    let n: usize = read();
    let mut g: Graph = graph_new(n);
    let mut e = 0;
    for _ in 0..n-1 {
        let mut a: usize = read();
        let mut b: usize = read();
        a -= 1; b -= 1;
        add_bi_edge(&mut g, &mut e, a, b, 0);
    }
    let mut max_sub_trees = vec![];
    for i in 0..n {
        let mut max_sub_tree = 0;
        for edge in g[i].iter() {
            max_sub_tree = std::cmp::max(max_sub_tree, dfs(&g, edge.dest, i));
        }
        max_sub_trees.push((max_sub_tree, i));
    }
    max_sub_trees.sort();
    if max_sub_trees[0].0 == max_sub_trees[1].0 {
        println!("{}", fact(n / 2) * fact(n / 2) % MOD);
        return;
    }
    let center = max_sub_trees[0].1;
    let mut vs = vec![];
    for edge in g[center].iter() {
        vs.push(dfs(&g, edge.dest, center));
    }
    let ans = solve(n, &vs);
    println!("{}", ans);
}