您的位置:首页 > 其它

HDU-4714-树形dp

2016-12-15 14:40 281 查看
题目大意:给定一棵树,每次删边或者增边代价为1,问把这棵树变成一个环最小代价是多少;

题目解析:删边肯定就要增边,所以答案的形式最后肯定是2*m+1,我们就需要求m的最小值;每次dfs的时候若果son的个数>=2,如果root是跟,那么需要删除n-2条边,如果不是根,我们的目标是把这棵树变成一根单链,所以先把跟root的这条边删掉,然后再删除n-2条边,所以一共是n-1条边,最后答案需要乘2+1,;

AC代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
const int maxn=1000010;
const int inf=0x3fffffff;
struct edge
{
int to,next;
}e[maxn<<1];
int tot,head[maxn],n,num;
void init()
{
tot=0;
memset(head,-1,sizeof(head));
}
void addedge(int u,int v)
{
e[tot].to=v;
e[tot].next=head[u];
head[u]=tot++;
}
int dfs(int root,int fa)
{
int t=0;
for(int i=head[root];i!=-1;i=e[i].next)
{
int v=e[i].to;
if(fa==v) continue;
t+=dfs(v,root);
}
if(t>1)
{
if(fa==-1) num+=t-2;
else num+=t-1;
return 0;
}
return 1;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
init();
num=0;
for(int i=1;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
int temp=dfs(1,-1);
printf("%d\n",2*num+1);

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