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 C (GCC 9.2.1) (judge verdict: Accepted)

#include <stdio.h>
#include <stdlib.h>

#define N	5000
#define MD	1000000007

int vv[N + 1], ff[N + 1], gg[N + 1];

long long choose(int n, int k) {
	return (long long) ff[n] * gg[k] % MD * gg[n - k] % MD;
}

void init() {
	int i;

	ff[0] = gg[0] = 1;
	for (i = 1; i <= N; i++) {
		vv[i] = i == 1 ? 1 : (long long) vv[i - MD % i] * (MD / i + 1) % MD;
		ff[i] = (long long) ff[i - 1] * i % MD;
		gg[i] = (long long) gg[i - 1] * vv[i] % MD;
	}
}

int *oj[N], oo[N];

void link(int i, int j) {
	int o = oo[i]++;

	if (o >= 2 && (o & o - 1) == 0)
		oj[i] = (int *) realloc(oj[i], o * 2 * sizeof *oj[i]);
	oj[i][o] = j;
}

int sz[N], n, c;

int dfs(int p, int i) {
	int o, centroid;

	sz[i] = 1;
	centroid = 1;
	for (o = 0; o < oo[i]; o++) {
		int j = oj[i][o];

		if (j != p) {
			if (dfs(i, j))
				return 1;
			if (sz[j] * 2 > n)
				centroid = 0;
			sz[i] += sz[j];
		}
	}
	if ((n - sz[i]) * 2 > n)
		centroid = 0;
	if (centroid) {
		if (c != -1)
			return 1;
		c = i;
	}
	return 0;
}

int main() {
	static int dp_[N + 1];
	int m, h, i, j, k, l, o, ans;

	init();
	scanf("%d", &n);
	for (i = 0; i < n; i++)
		oj[i] = (int *) malloc(2 * sizeof *oj[i]);
	for (h = 0; h < n - 1; h++) {
		scanf("%d%d", &i, &j), i--, j--;
		link(i, j), link(j, i);
	}
	c = -1;
	if (dfs(-1, 0)) {
		printf("%lld\n", (long long) ff[n / 2] * ff[n / 2] % MD);
		return 0;
	}
	dp_[0] = 1, m = 0;
	for (o = 0; o < oo[c]; o++) {
		int s;

		j = oj[c][o], s = sz[j] < sz[c] ? sz[j] : n - sz[c];
		for (k = m; k >= 0; k--) {
			int x = dp_[k];

			if (x == 0)
				continue;
			for (l = 1; l <= s; l++) {
				int c = choose(s, l);

				dp_[k + l] = (dp_[k + l] + (long long) c * c % MD * ff[l] % MD * x) % MD;
			}
		}
		m += s;
	}
	ans = 0;
	for (k = 0; k <= n; k++)
		ans = (ans + (long long) dp_[k] * ff[n - k] * (k % 2 == 0 ? 1 : -1)) % MD;
	if (ans < 0)
		ans += MD;
	printf("%d\n", ans);
	return 0;
}