树形结构溯源dp
codeforces题目链接 - F. Gardening Friends
//yigan_Eins
#include <bits/stdc++.h>
using namespace std;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
//using i128 = __int128;
//using u128 = unsigned __int128;
#define int long long
#define pb emplace_back
#define all(x) (x).begin(),(x).end()
#define all2(x) (x).begin() + 1,(x).end()
typedef long long ll;
typedef pair<int,int> PII;
const ll inf = 4e18;
ll P = 1e9 + 7;
const ll MOD = 998244353;
const ll MAX_INT = 2147483647;//2e9
const ll MAX_LL = 9223372036854775807;//9e18
ll gcd(ll a,ll b){return b == 0 ? a : gcd(b,a % b);}
ll lcm(ll a,ll b){return a / gcd(a,b) * b;}
ll qmi(ll a,ll b)
{
ll res = 1;
while(b)
{
if(b & 1)res = res * a % P;
a = a * a % P;
b >>= 1;
}
return res;
}
ll inv(ll x){return qmi(x,P - 2);}
ll mo(ll x){return (x % P + P) % P;}
struct CMP
{
bool operator () (const array<int,4> &f1,const array<int,4> &f2)
{
return f1[0] > f2[0];//为true后一个值放到堆顶
}
};
void YES(bool ok)
{
cout << (ok ? "YES" : "NO") << '\n';
}
void Yes(bool ok)
{
cout << (ok ? "Yes" : "No") << '\n';
}
void print(vector<string> a)
{
for(auto x : a) {
cout << x << " ";
}
cout << '\n';
}
int dx[] = {0,0,1,-1,-1,1,1,-1};
int dy[] = {1,-1,0,0,1,1,-1,-1};
const ll N = 2e5 + 9;
vector<int> g[N];
void solve(int t_id)
{
int n,k,c;cin >> n >> k >> c;
for(int i = 1;i <= n - 1;i++) {
int u,v;cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
//处理每个节点到底部的最大高度
vector<int> d(n + 1);
auto dfs = [&](auto &&self,int u,int fa) -> void {
int res = 0;
for(auto y : g[u]) {
if(y == fa)continue;
self(self,y,u);
res = max(res,d[y]);
}
d[u] = res + 1;
};
int ans = 0;
//fa_d为父节点不经过u节点的最大高度,res为转移根的成本
auto dfs1 = [&](auto &&self,int u,int fa,int fa_d,int res) -> void {
vector<PII> vt;
int ma = 0;
for(auto y : g[u]) {
if(y == fa)continue;
vt.push_back({d[y],y});
ma = max(ma,d[y]);
}
sort(all(vt),greater<PII>());
ans = max(ans,max(fa_d + 1,ma) * k - res);
// cout << u << " " << fa_d + 1 << " " << max(fa_d + 1,ma) << " " << res << '\n';
for(auto y : g[u]) {
if(y == fa)continue;
//更新fa_d
int ress = fa_d + 1;
if(vt.size()) {
if(vt[0].second == y) { //子节点的最大高度经过y
if(vt.size() >= 2) { //取次大高度
ress = max(ress,vt[1].first);
}
}
else ress = max(ress,vt[0].first); //子节点的最大高度不经过y,取最大高度
}
self(self,y,u,ress,res + c);
}
};
dfs(dfs,1,0);
dfs1(dfs1,1,0,-1,0);
cout << ans << '\n';
//
for(int i = 1;i <= n;i++) {
g[i].clear();
}
}
signed main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int t = 1;
cin >> t;
for(int i = 1;i <= t;i++) {
solve(i);
}
return 0;
}