poj 1463 Strategic game(树状DP…
2013-04-23 09:26
417 查看
题意:有N个点,每两个点至多只有一条边,如果在一个结点上放一个士兵,那他能看守与之相连的边,问最少放多少个兵能,把所有的点能看守住。
思路:题中已明确表示 为一棵树,所以想到了用树状DP,状态方程:
dp[root][1] +=
dp[leaf][0];
//根结点放一兵的话,等于 它所有叶结点所须最少兵的和
dp[root][0] +=
dp[leaf][1];
//根结点不放 那它的叶结点都放
dp[root][0] = min
(dp[root][1],dp[root][0]);
//最后,dp[root][0] 表示 要看守这个结点所须的最少兵
//296K
469MS
#include <stdio.h>
#include <string.h>
#define M 1550
int dp[M][2],tree[M][15];
//dp[i][1] 为在i放一兵 能看守这棵子树所须的人
//dp[i][0] 为i不放 能看守这棵子树所须的人
bool vis[M];
int min (int a,int b)
{
return a
> b ? b : a;
}
void dfs (int root)
{
int sum =
tree[root][0];
vis[root] =
true;
for (int i =
1; i <= sum ; i ++)
{
int leaf = tree[root][i];
if
(vis[leaf])
//如果该结点已访问过,就不用再访问(不然就会死循环)
continue;
dfs (leaf);
dp[root][1] += dp[leaf][0];
dp[root][0] += dp[leaf][1];
dp[root][0] = min (dp[root][1],dp[root][0]);
}
}
int main ()
{
int
n,i,m,node,root;
char
str[10];
while
(~scanf ("%d",&n))
{
memset (tree,0,sizeof(tree));
memset (dp,0,sizeof(dp));
memset (vis,false,sizeof(vis));
for (i = 1; i <= n; i ++)
dp[i][1] = 1;
for (i = 0; i < n; i ++)
{
scanf ("%s",str);
sscanf
(str,"%d:(%d)",&root,&m);
++root;
while (m --)
{
scanf ("%d",&node);
++node;
tree[root][++tree[root][0]] = node;
tree[node][++tree[node][0]] = root;
}
}
dfs (1);
printf ("%d\n",dp[1][0]);
}
return
0;
}
思路:题中已明确表示 为一棵树,所以想到了用树状DP,状态方程:
dp[root][1] +=
dp[leaf][0];
//根结点放一兵的话,等于 它所有叶结点所须最少兵的和
dp[root][0] +=
dp[leaf][1];
//根结点不放 那它的叶结点都放
dp[root][0] = min
(dp[root][1],dp[root][0]);
//最后,dp[root][0] 表示 要看守这个结点所须的最少兵
//296K
469MS
#include <stdio.h>
#include <string.h>
#define M 1550
int dp[M][2],tree[M][15];
//dp[i][1] 为在i放一兵 能看守这棵子树所须的人
//dp[i][0] 为i不放 能看守这棵子树所须的人
bool vis[M];
int min (int a,int b)
{
return a
> b ? b : a;
}
void dfs (int root)
{
int sum =
tree[root][0];
vis[root] =
true;
for (int i =
1; i <= sum ; i ++)
{
int leaf = tree[root][i];
if
(vis[leaf])
//如果该结点已访问过,就不用再访问(不然就会死循环)
continue;
dfs (leaf);
dp[root][1] += dp[leaf][0];
dp[root][0] += dp[leaf][1];
dp[root][0] = min (dp[root][1],dp[root][0]);
}
}
int main ()
{
int
n,i,m,node,root;
char
str[10];
while
(~scanf ("%d",&n))
{
memset (tree,0,sizeof(tree));
memset (dp,0,sizeof(dp));
memset (vis,false,sizeof(vis));
for (i = 1; i <= n; i ++)
dp[i][1] = 1;
for (i = 0; i < n; i ++)
{
scanf ("%s",str);
sscanf
(str,"%d:(%d)",&root,&m);
++root;
while (m --)
{
scanf ("%d",&node);
++node;
tree[root][++tree[root][0]] = node;
tree[node][++tree[node][0]] = root;
}
}
dfs (1);
printf ("%d\n",dp[1][0]);
}
return
0;
}
相关文章推荐
- ACM: 树状DP 动态规划题 poj 1463 …
- poj&nbsp;2996&nbsp;Help&nbsp;Me&nbsp;with&nbsp;the&nbsp;Game
- POJ 1753 Flip Game
- poj 1463 Strategic game DP
- Strategic game POJ - 1463
- poj1286(polya计数&nbsp;套模版)
- poj 1426 Find The Multiple(Spec…
- poj 3665 icow
- poj&nbsp;2485&nbsp;highways(prim)
- poj&nbsp;1466&nbsp;Girls&nbsp;and&nbsp;Boys(最大独立…
- poj&nbsp;1716&nbsp;Integer&nbsp;Intervals(差分…
- poj&nbsp;3160&nbsp;Father&nbsp;Christmas&nbsp;flymou…
- poj&nbsp;2584&nbsp;T-Shirt&nbsp;Gumbo(最大流&nbsp;s…
- poj&nbsp;1274&nbsp;The&nbsp;Perfect&nbsp;Stall(二分…
- POJ&nbsp;3006
- POJ&nbsp;1799
- POJ&nbsp;2136
- POJ 1004 Financial Management(…
- poj 2299_归并排序
- poj 2251