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 Java8 (OpenJDK 1.8.0) (judge verdict: Wrong Answer)



import java.io.*;
import java.util.*;

/**
 * 
 * @author kuppu Centroid decomposition
 */
public class Main {
	static int mod = 1_000_000_007;
	static long fact[] = new long[5003];;
	static long dp[][] = new long[2][10000];
	static LinkedList<Integer> g[] = new LinkedList[5003];
	static long c[][] = new long[5003][5003];
	static int centroid = 0;
	static int sz[] = new int[5003];
	static int a[] = new int[5003];
	static int m;

	static void dfs(int v, int par) {
		sz[v] = 1;
		for (int u : g[v]) {
			if (u == par)
				continue;
			dfs(u, v);
			sz[v] += sz[u];
		}
	}

	static long add(long x, long y) {
		x += y;
		if (x >= mod)
			return x - mod;
		return x;
	}

	static long sub(long x, long y) {
		x -= y;
		if (x < 0)
			return x + mod;
		return x;
	}

	static long mul(long x, long y) {
		x *= y;
		return x % mod;
	}

	public static void Solve(int n) {
		dp[0][0] = 1;
		for (int i = 0; i < m; i++) {
			for (int x = 0; x <= n; x++)
				dp[1][x] = 0;
			for (int x = 0; x <= n; x++) {
				if (dp[0][x] == 0) continue;
				for (int y = 0; y <= a[i]; y++)
					dp[1][x + y] = add(dp[1][x + y], mul(mul(dp[0][x], fact[y]), mul(c[a[i]][y], c[a[i]][y])));
			}
			for (int x = 0; x <= n; x++)
				dp[0][x] = dp[1][x];
		}
		long ans = 0;
		for (int x = 0; x <= n; x++) {
			long val = mul(dp[0][x], fact[n - x]);
			if ((x & 1)!=0)
				ans = sub(ans, val);
			else
				ans = add(ans, val);
		}
		System.out.println(ans);

	}

	public static void main(String args[]) throws Exception {

		FastReader sc = new FastReader();
		PrintWriter out = new PrintWriter(System.out);
		fact[0] = 1;
		for (int i = 1; i <= 5000; i++) {
			fact[i] = mul(fact[i - 1], i);
		}
		c[0][0] = 1;
		for (int i = 0; i < 5000; i++)
			c[i][0] = c[i][i] = 1;
		for (int i = 1; i < 5003; i++) {
			for (int j = 1; j < i; j++) {
				c[i][j] = add(c[i - 1][j], c[i - 1][j - 1]);
			}
		}
		for (int i = 0; i < 5001; i++) {
			g[i] = new LinkedList<>();
		}
		int n = sc.nextInt();
		for (int i = 1; i < n; i++) {
			int u = sc.nextInt() - 1;
			int v = sc.nextInt() - 1;
			g[u].add(v);
			g[v].add(u);

		}
		dfs(0, -1);
		int v = 0;
		while (true) {
			int w = -1;
			for (int u : g[v]) {
				if (sz[v] < sz[u]) {
					continue;
				}
				if (2 * sz[u] == n) {
					w = u;
				}
			}
			if (w == -1)
				break;
			v = w;
		}
		dfs(v, -1);
		for (int u : g[v]) {
			a[m] = sz[u];
			if (n == 2 * a[m]) {
				System.out.println(mul(fact[a[m]], fact[a[m]]));
				return;
			}
			m++;
		}
		
		Solve(n);
		out.close();

	}

	static class FastReader {
		BufferedReader br;
		StringTokenizer st;

		public FastReader() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		String next() {
			while (st == null || !st.hasMoreElements()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

		String nextLine() {
			String str = "";
			try {
				str = br.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return str;
		}
	}
}