您的位置:首页 > 其它

UVA 1292-Strategic game(树形DP)

2015-03-10 00:22 337 查看
题目大意:给出一棵树,在某个选择某个结点可以覆盖和它相连的所有边,问最少选多少个结点所有边都被覆盖。

首先将无根树转化为有根树,0为根。
用d[i][0]表示不选择结点i时覆盖以结点i为根的子树最少要多少个结点,用d[i][1]表示选择结点i时覆盖以结点i为根的子树最少要多少个结点。若结点i不选,为了和覆盖所有和结点i相连的结点,则每个儿子都必须选,若结点i选,则每个儿子选择较小的那个值。按DFS顺序递推。

状态转移方程:
d[i][0]=sum { d[u][1] }(u是i的儿子)
d[i][1]=sum { min { d[u][0],d[u][1] } }+1(u是i的儿子)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<vector>
using namespace std;
int a[30];
int d[1510][2];
char e[1510];
int par[1510];
vector<int> G[1510];
void dfs(int u);
void rootedtree(int u,int fa);
int main(void)
{
int i,j,u,n,sump,top,lo;
while(scanf("%d",&n)==1)
{
for(i=0;i<n;i++)
{
G[i].clear();
}
for(i=1;i<=n;i++)
{
scanf("%s",e);
lo=strlen(e);
j=top=0;
while(j<lo)
{
if((e[j]>='0')&&(e[j]<='9'))
{
sump=0;
while((e[j]>='0')&&(e[j]<='9'))
{
sump=sump*10+e[j]-'0';
j++;
}
top++;
a[top]=sump;
}
else
{
j++;
}
}
for(j=1;j<=a[2];j++)
{
scanf("%d",&u);
G[a[1]].push_back(u);
G[u].push_back(a[1]);
}
}
rootedtree(0,-1);
for(i=0;i<n;i++)
{
G[i].clear();
}
for(i=1;i<n;i++)
{
G[par[i]].push_back(i);
}
dfs(0);
printf("%d\n",d[0][0]>d[0][1]?d[0][1]:d[0][0]);
}
return 0;
}
void dfs(int u)
{
int i,p,minp,sump;
p=G[u].size();
if(p==0)
{
d[u][0]=0;
d[u][1]=1;
}
else
{
for(i=0;i<p;i++)
{
dfs(G[u][i]);
}
sump=minp=0;
for(i=0;i<p;i++)
{
minp=minp+(d[G[u][i]][0]>d[G[u][i]][1]?d[G[u][i]][1]:d[G[u][i]][0]);
sump=sump+d[G[u][i]][1];
}
d[u][0]=sump;
d[u][1]=minp+1;
}
}
void rootedtree(int u,int fa)
{
int i,v,p;
p=G[u].size();
for(i=0;i<p;i++)
{
v=G[u][i];
if(v!=fa)
{
par[v]=u;
rootedtree(v,u);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  uva dp