去年金华邀请赛的B题, 其实就是个挺简单的树上的统计
#include <iostream>
#include <vector>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
using namespace std;
const int N = 50005;
const int M = N << 1;
typedef long long LL;
const LL INF = 1LL << 60;
vector<int> vec;
LL dep[N], sum[N], key[N], son[N];
int head[N], to[M], next[M];
int tot, n, I, R;
LL res;
void init() {
for (int i = 1; i <= n; i++) {
head[i] = -1, son[i] = 1, sum[i] = 0;
}
tot = 0;
}
void add(int u, int v) {
to[tot] = v, next[tot] = head[u], head[u] = tot++;
to[tot] = u, next[tot] = head[v], head[v] = tot++;
}
void dfs(int u, int d, int fa) {
dep[u] = d;
for (int i = head[u]; i != -1; i = next[i]) {
int v = to[i];
if (v == fa) continue;
dfs(v, d + 1, u);
sum[u] += sum[v] + son[v];
son[u] += son[v];
}
}
void dfs(int u, int fa) {
if (fa == 0) {
key[u] = sum[u];
}
else {
key[u] = key[fa] - 2 * son[u] + n;
}
if (key[u] < res) {
res = key[u];
vec.clear();
vec.push_back(u);
}
else if (key[u] == res) {
vec.push_back(u);
}
for (int i = head[u]; i != -1; i = next[i]) {
int v = to[i];
if (v == fa) continue;
dfs(v, u);
}
}
int main() {
int test, u, v;
scanf("%d", &test);
while (test--) {
scanf("%d%d%d", &n, &I, &R);
init();
for (int i = 0; i < n - 1; i++) {
scanf("%d%d", &u, &v);
add(u, v);
}
res = INF;
dfs(1, 0, 0);
dfs(1, 0);
sort(vec.begin(), vec.end());
printf("%lld\n", I * R * I * res);
for (int i = 0; i < vec.size(); i++)
printf("%d ", vec[i]);
printf("\n\n");
}
return 0;
}