其实这个题还不是很懂,略微懂了个皮毛,恕在下愚昧无知。
#include<bits/stdc++.h>
using namespace std;
const int maxn=300+10;
struct node{
int v;
int next;
int w;
}p[maxn<<1];
int head[maxn<<1];
int cnt;
int n,m,k;
int dp[maxn][maxn][2];
//dp[i][j][k]表示城市i及其子树中电网1有j个城市,k表示当城市i本身是否输入电网一。
void init(){
cnt=0;
memset(head,-1,sizeof(head));
memset(dp,0x3f,sizeof(dp));
}
void addedge(int u,int v,int w){
p[++cnt].v=v;
p[cnt].w=w;
p[cnt].next=head[u];
head[u]=cnt;
}
void dfs(int u,int fa){
dp[u][1][1]=0;
dp[u][0][0]=0;
//init
for(int e=head[u];e!=-1;e=p[e].next){
int v=p[e].v;
if(v!=fa){
dfs(v,u);
if(m==2){
dp[u][1][1]+=dp[v][0][0];
dp[u][0][0]+=dp[v][0][0]+p[e].w;
}
}
}
for(int e=head[u];e!=-1;e=p[e].next){
int v=p[e].v;
if(v==fa) continue;
for(int j=k;j>=0;j--){
for(int i=0;i<=j;i++){
if(m==2){
dp[u][j][0]=min(dp[u][j][0],dp[u][j-i][0]-dp[v][0][0]+dp[v][i][0]);
//之前初始化的时候u中加上了dp[v][0][0],所以现在在v中取出e个自然不包括v中去取0个。
dp[u][j][0]=min(dp[u][j][0],dp[u][j-i][0]+dp[v][i][1]-dp[v][0][0]-p[e].w);
//之前初始化的时候u中加上了dp[v][0][0]+p[e].w,所以现在在v中取出e个自然不包括v中去取0个,并且v在电网一中,所以减去p[e].w。
dp[u][j][1]=min(dp[u][j][1],dp[u][j-i][1]+dp[v][i][0]-dp[v][0][0]);
dp[u][j][1]=min(dp[u][j][1],dp[u][j-i][1]+dp[v][i][1]-dp[v][0][0]+p[e].w);
}else{
dp[u][j][0]=min(dp[u][j][0],dp[u][j-i][0]+dp[v][i][0]);
dp[u][j][0]=min(dp[u][j][0],dp[u][j-i][0]+dp[v][i][1]);
dp[u][j][1]=min(dp[u][j][1],dp[u][j-i][1]+dp[v][i][0]);
dp[u][j][1]=min(dp[u][j][1],dp[u][j-i][1]+dp[v][i][1]+p[e].w);
}
}
}
}
}
int main(){
init();
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<n;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
addedge(v,u,w);
}
if(k+m-1>n){
printf("-1\n");
return 0;
}
dfs(1,0);
printf("%d\n",dp[1][k][1]);
return 0;
}