static ModNum[] CalcPermutations(int head, int count) { var array = new ModNum[count + 1]; array[0] = 1; for (var i = 0; i < count; i++) { array[i + 1] = array[i] * (head - i); } return(array); }
static void Main(string[] args) { // 入力の取得 var inputs = Console.ReadLine().Split().Select(int.Parse).ToArray(); int n = inputs[0], k = inputs[1]; var nodes = Enumerable.Range(1, n).Select(x => new Node()).ToArray(); for (var i = 0; i < n - 1; i++) { var edge = Console.ReadLine().Split().Select(int.Parse).ToArray(); int indexA = edge[0] - 1, indexB = edge[1] - 1; Node.Unite(nodes[indexA], nodes[indexB]); } var answer = new ModNum(k); if (n > 1) { // 簡易化するため、隣接ノードが1つの末端ノードを root として選定 var root = nodes.First(x => x.NeighborCount == 1); var maxChildCount = nodes.Max(x => x.ChildCount); if (k - 2 < maxChildCount) { answer = 0; // 距離2以内のノード数がkより大きくなる場合、塗る方法がないので0 } else { // root 直下のノードの色の塗り方(root 以外の色 k-1 通り) answer *= k - 1; // root 以外のノードについて、子ノードの色の塗り方を乗算していく var permutations = CalcPermutations(k - 2, maxChildCount); foreach (var node in nodes) { // 子ノードを持たない末端ノード(root 含む)除外 if (node.ChildCount == 0) { continue; } answer *= permutations[node.ChildCount]; } } } // 解答の出力 Console.WriteLine(answer.X); }