分析:树形DP
主要看x
dp[u][1]=min{dp[v0][1]−dp[v0][0]}+∑{dp[v][0]}
dp[u][0]
:如果
u
的子节点中有
代码:
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,x,y) for(int i = x;i < y;++ i)
#define IFOR(i,x,y) for(int i = x;i > y;-- i)
#define pb push_back
typedef long long LL;
typedef vector <int> VI;
const int maxn = 200010;
const int inf = 1<<30;
int dp[maxn][2],du[maxn],n;
LL x,y;
VI mat[maxn];
void dfs(int u,int fa){
int minx = inf;
int num = 0,sum = 0;
FOR(i,0,(int)mat[u].size()){
int v = mat[u][i];
if(v == fa) continue;
dfs(v,u);
if(dp[v][0] == dp[v][1]) num ++;
sum += dp[v][0];
minx = min(dp[v][1]-dp[v][0],minx);
}
if(minx == inf) dp[u][1] = 1;
else dp[u][1] = minx + sum;
if(num >= 2) dp[u][0] = dp[u][1]-1;
else dp[u][0] = dp[u][1];
//printf("id:%d\t dp[u][0]:%d\t dp[u][1]:%d\n",u,dp[u][0],dp[u][1]);
}
int main(){
scanf("%d%I64d%I64d",&n,&x,&y);
FOR(i,0,n+1) mat[i].clear(),du[i] = 0;;
FOR(i,1,n){
int u,v; scanf("%d%d",&u,&v);
mat[u].pb(v); mat[v].pb(u);
du[u] ++; du[v] ++;
}
if(x >= y){
bool flag = false;
FOR(i,1,n+1) if(du[i] == n-1) {
flag = true;break;
}
if(flag){
printf("%I64d\n",y*(n-2)+x);
}
else{
printf("%I64d\n",y*(n-1));
}
}
else{
dfs(1,-1);
printf("%I64d\n",(dp[1][0]-1)*y+(n-dp[1][0])*x);
}
return 0;
}