您的位置:首页 > 其它

BZOJ 1907 树DP 解题报告

2017-09-22 14:00 309 查看
1907: 树的路径覆盖

Description



Input



Output



Sample Input

1

7

1 2

2 3

2 4

4 6

5 6

6 7

Sample Output

3

【解题报告】

首先将所有的链都考虑成以链上所有点的LCA为转折点的V字形

那么点有两种:转折点和非转折点

因此我们选择两种状态进行转移:还会和父亲组成链的状态和成为转折点的状态

代码如下:

/**************************************************************
Problem: 1907
User: onepointo
Language: C++
Result: Accepted
Time:204 ms
Memory:1500 kb
****************************************************************/

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 10010

int t,n,dp
[2];
int cnt,head
;
struct Edge{int to,nxt;}e[N<<1];

void adde(int u,int v)
{
e[++cnt].to=v;e[cnt].nxt=head[u];head[u]=cnt;
e[++cnt].to=u;e[cnt].nxt=head[v];head[v]=cnt;
}
void dfs(int u,int fa)
{
int tmp=0;dp[u][0]=dp[u][1]=1;
for(int i=head[u];~i;i=e[i].nxt)
{
int v=e[i].to;
if(v==fa) continue;
dfs(v,u);
dp[u][0]=min(dp[u][0]+dp[v][0],dp[u][1]+dp[v][1]-1);
dp[u][1]=min(dp[u][1]+dp[v][0],tmp+dp[v][1]);
tmp+=dp[v][0];
}
}
int main()
{
for(scanf("%d",&t);t;--t)
{
cnt=-1;
memset(head,-1,sizeof(head));
scanf("%d",&n);
for(int i=1;i<n;++i)
{
int u,v;scanf("%d%d",&u,&v);
adde(u,v);
}
dfs(1,1);
printf("%d\n",dp[1][0]);
}
return 0;
}

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