publicstaticvoidsolve() { intn= io.nextInt(), m = n * (n - 1) / 2; int[] b = newint[m]; for (inti=0; i < m; i++) { b[i] = io.nextInt(); } Arrays.sort(b); for (inti=0; i < m; i += --n) { io.print(b[i] + " "); } io.println(b[m - 1]); }
如果要在 u 和 v 之间添加一条边,那么首先要求 u 和 v 之间没有直接相连的边,并且新添加的边的权重要大于 w 小于 S,这样才能保证最小生成树是给定的树。暴力求解的时间复杂度是 O(n2),我们可以利用 Kruskal 算法优化,对边按权重从小到大排序,然后在连接两个顶点时计算两棵树之间顶点连接的方案数,将所有计算结果相乘就是答案。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
privatestaticfinalintMOD=998244353;
publicstaticvoidsolve() { intn= io.nextInt(), S = io.nextInt(); List<int[]> edges = newArrayList<>(); for (inti=0; i < n - 1; i++) { intu= io.nextInt(), v = io.nextInt(), w = io.nextInt(); edges.add(newint[]{u, v, w}); } edges.sort((a, b) -> a[2] - b[2]); longans=1L; UnionFinduf=newUnionFind(n + 1); for (int[] e : edges) { intu= e[0], v = e[1], w = e[2]; ans = (ans * fastPower(S - w + 1, (long) uf.size(u) * uf.size(v) - 1)) % MOD; uf.union(u, v); } io.println(ans); }