您的位置:首页 > 其它

HDU 5758 Explorer Bo (树形DP)

2016-07-27 14:46 393 查看
题目:给你一棵树,用最少的链去覆盖这棵树,求链的最小总长度。

解析:num为叶子节点数,显然链数是(num+1)/2。如果是偶数,就是叶子节点到叶子节点,如果是奇数,那么就是在奇数-1情况下的树下加一条叶子到其祖先的链。

偶数的情况:从一个非叶子节点出发,如果其子节点的叶子节点是偶数,则ans+=2,如果是奇数,ans+=1。

奇数的情况:枚举一下那条单链所在的子树。

设dp[u][i][j] 在u的子树中,u的父边需要经过i次,j表示单链是否在该子树中。j=1就额外枚举单链所在子树即可,如果单链在该子树中,那么该树中的有效叶子节点-1(即奇数变偶数,偶数变奇数)。

[code]:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>

using namespace std;
const int maxn = 2e5+5;

struct Nod{
int b,next;
void init(int b,int next){
this->b=b;this->next=next;
}
}buf[2*maxn];
int n,E[maxn],len,cnt[maxn],ans,deg[maxn];
int dp[maxn][3][2];

void init(){
ans = len = 0;
memset(E,-1,sizeof(E));
memset(dp,-1,sizeof(dp));
memset(deg,0,sizeof(deg));
}
void add_edge(int a,int b){
buf[len].init(b,E[a]);E[a]=len++;
buf[len].init(a,E[b]);E[b]=len++;
deg[a]++;deg[b]++;
}

void pre_dfs(int u,int pre){
int i,v,f = 0;
cnt[u] = 0;
for(i = E[u];i != -1;i = buf[i].next){
v = buf[i].b;
if(v == pre) continue;
pre_dfs(v,u);
cnt[u]+=cnt[v];
f = 1;
}
if(!f) cnt[u] = 1;
}
int dfs(int u,int pre,int s1,int s2){
if(dp[u][s1][s2]!=-1) return dp[u][s1][s2];
int i,v,ans = 0,num = -s1,tmp;
for(i = E[u];i != -1;i = buf[i].next){
v = buf[i].b;
if(v == pre) continue;
num += cnt[v];
if(cnt[v]&1) ans += dfs(v,u,1,0)+1;
else ans += dfs(v,u,2,0)+2;
}
if(s2){
tmp = 0x3f3f3f3f;
for(i = E[u];i != -1;i = buf[i].next){
v = buf[i].b;
if(v == pre) continue;
if(cnt[v]&1){
if(cnt[v]==1) tmp = min(tmp,ans);
else tmp = min(tmp,ans+dfs(v,u,2,1)+2-(dfs(v,u,1,0)+1));
}else tmp = min(tmp,ans+dfs(v,u,1,1)+1-(dfs(v,u,2,0)+2));
}
ans = tmp;
}
return dp[u][s1][s2] = ans;
}

int main(){
int i,j,cas,u,v;
scanf("%d",&cas);
while(cas--){
scanf("%d",&n);
init();
for(i = 1;i < n;i++){
scanf("%d%d",&u,&v);
add_edge(u,v);
}
if(n == 2){
puts("1");
continue;
}
int root=-1,num = 0;
for(i = 1;i <= n;i++){
if(deg[i]!=1&&root==-1){
root = i;
}
num += deg[i]==1;
}
pre_dfs(root,-1);
printf("%d\n",dfs(root,-1,0,num&1));
}

return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: