【♂Not The Triumph♂O(∩_∩)O哈哈~But The Struggle♂】

竞赛决不是捷径,它只是另一种艰辛的生活方式。得到与失去,只有时间会去评判;成功与失败,只有历史能去仲裁。我不会永远成功,正如我不会永远失败一样

  C++博客 :: 首页 :: 联系 ::  :: 管理
  6 Posts :: 239 Stories :: 25 Comments :: 0 Trackbacks

常用链接

留言簿(7)

我参与的团队

搜索

  •  

积分与排名

  • 积分 - 107646
  • 排名 - 231

最新评论

阅读排行榜

评论排行榜

Description
Bob喜欢玩电脑游戏,特别是战略游戏。但是他经常无法找到快速玩过游戏的办法。现在他有个问题。他要建立一个古城堡,城堡中的路形成一棵树。他要在这棵树的结点上放置最少数目的士兵,使得这些士兵能了望到所有的路。注意,某个士兵在一个结点上时,与该结点相连的所有边将都可以被了望到。
请你编一程序,给定一树,帮Bob计算出他需要放置最少的士兵。

Input
输入文件中数据表示一棵树,描述如下:
第一行 N,表示树中结点的数目。
第二行至第N+1行,每行描述每个结点信息,依次为:该结点标号i,k(后面有k条边与结点I相连),接下来k个数,分别是每条边的另一个结点标号r1,r2,...,rk。
对于一个n(0 < n <= 1500)个结点的树,结点标号在0到n-1之间,在输入文件中每条边只出现一次。

Output
输出文件仅包含一个数,为所求的最少的士兵数目。

Sample Input
4
0 1 1
1 2 2 3
2 0
3 0

Sample Output
1


【参考程序】:

#include<cstring>
#include
<cstdio>
#include
<iostream>
using namespace std;

int F[2][1510],now[1510],child[3200],next[3200
];
bool vis[1510
];
int
 n;
int Min(int x,int
 y)
{
    
return x<y?
x:y;
}
void tree_dp(int
 k)
{
    vis[k]
=true; F[0][k]=0; F[1][k]=1
;
    
while (now[k]>0
)
    {
        
if (!
vis[child[now[k]]])
        {
            tree_dp(child[now[k]]);
            F[
0][k]+=F[1
][child[now[k]]];
            F[
1][k]+=Min(F[1][child[now[k]]],F[0
][child[now[k]]]);
        }
        now[k]
=
next[now[k]];
    }
}
int
 main()
{
    scanf(
"%d",&
n);
    memset(now,
-1,sizeof
(now));
    
int c=0
,a,b,k;
    
for (int i=1;i<=n;i++
)
    {
        scanf(
"%d%d",&a,&
k);
        
for (int j=1;j<=k;j++
)
        {
            scanf(
"%d",&
b);
            c
++
;
            child[c]
=a; next[c]=now[b]; now[b]=
c;
            c
++
;
            child[c]
=b; next[c]=now[a]; now[a]=
c;
        }
    }
    memset(F,
0,sizeof
(F));
    memset(vis,
false,sizeof
(vis));
    tree_dp(
0
);
    printf(
"%d\n",Min(F[0][0],F[1][0
]));
    
return 0
;
}
posted on 2009-08-24 11:42 开拓者 阅读(421) 评论(0)  编辑 收藏 引用 所属分类: 树形DP

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理