POJ 1463 Strategic game 最小点覆盖集(树形dp)

点击打开链接

Strategic game

Time Limit: 2000MS   Memory Limit: 10000K
Total Submissions: 6105   Accepted: 2808

Description

Bob enjoys playing computer games, especially strategic games, but sometimes he cannot find the solution fast enough and then he is very sad. Now he has the following problem. He must defend a medieval city, the roads of which form a tree. He has to put the
minimum number of soldiers on the nodes so that they can observe all the edges. Can you help him?

Your program should find the minimum number of soldiers that Bob has to put for a given tree.

For example for the tree:

the solution is one soldier ( at the node 1).

Input

The input contains several data sets in text format. Each data set represents a tree with the following description:

  • the number of nodes
  • the description of each node in the following format 

    node_identifier:(number_of_roads) node_identifier1 node_identifier2 ... node_identifiernumber_of_roads

    or

    node_identifier:(0)

The node identifiers are integer numbers between 0 and n-1, for n nodes (0 < n <= 1500);the number_of_roads in each line of input will no more than 10. Every edge appears only once in the input data.

Output

The output should be printed on the standard output. For each given input data set, print one integer number in a single line that gives the result (the minimum number of soldiers). An example is given in the following:

Sample Input

4
0:(1) 1
1:(2) 2 3
2:(0)
3:(0)
5
3:(3) 1 4 2
1:(1) 0
2:(0)
0:(0)
4:(0)

Sample Output

1
2

Source

Southeastern Europe 2000

给你一颗树,让你求最小点覆盖。

最小点覆盖:从V中取尽量少的点组成一个集合,使得E中所有边都与取出来的点相连。

dp[i][0]表示点i属于点覆盖,并且以点i为根的子树中所连接的边都被覆盖的情况下点覆盖集中所包含最少点的个数。

dp[i][1]表示点i不属于点覆盖,且以i为根的子树中所连接的边都被覆盖的情况下点覆盖集中所包含最少点的个数。

对于第一种状态dp[i][0],等于每个儿子节点的两种状态的最小值之和+1,方程为:dp[i][0]=1+∑(p[u]=i)min(dp[u][0],dp[u][1]).

对于第二种状态dp[i][1],要求所有与i连接的边都被覆盖,但是i点不属于点覆盖,那么i点所有孩子子节点都必须属于覆盖点,即对于点i的第二种状态与所有子节点的第一种状态有关,在树枝上等于所有子节点的第一种状态的和,方程为:dp[i][1]=∑(p[u]=i)dp[u][0].

//6508K	375MS
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define M 1507
using namespace std;
int head[M],nodes;
int dp[M][M];
struct E
{
    int v,next;
}edge[M*M];
void addedge(int u,int v)
{
    edge[nodes].v=v;edge[nodes].next=head[u];
    head[u]=nodes++;
}
void DP(int u,int p)
{
    dp[u][0]=1;
    dp[u][1]=0;
    int k,v;
    for(k=head[u];k!=-1;k=edge[k].next)
    {
        v=edge[k].v;
        if(v==p)continue;
        DP(v,u);
        dp[u][0]+=min(dp[v][0],dp[v][1]);
        dp[u][1]+=dp[v][0];
    }
}
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        memset(head,-1,sizeof(head));
        nodes=0;
        int u,k,v;
        for(int i=0;i<n;i++)
        {
            scanf("%d:(%d)",&u,&k);
            while(k--)
            {
                scanf("%d",&v);
                addedge(u,v);
                addedge(v,u);
            }
        }
        DP(0,0);
        printf("%d\n",min(dp[0][0],dp[0][1]));
    }
    return 0;
}

POJ 1463 Strategic game 最小点覆盖集(树形dp),码迷,mamicode.com

时间: 2024-12-08 08:50:55

POJ 1463 Strategic game 最小点覆盖集(树形dp)的相关文章

POJ 3401 Asteroids 求最小点覆盖集

把行和列都看做是点,小行星看成是边的话,那么这个显然就是求一个最小点覆盖集的问题. 最小点覆盖 == 最大匹配 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #inc

POJ1463 Strategic game (最小点覆盖 or 树dp)

题目链接:http://poj.org/problem?id=1463 给你一棵树形图,问最少多少个点覆盖所有的边. 可以用树形dp做,任选一点,自底向上回溯更新. dp[i][0] 表示不选i点 覆盖子树所有边的最少点个数,那选i点的话,那么i的邻接节点都是必选的,所以dp[i][0] += dp[i.son][1] dp[i][1] 表示选i点 覆盖子树所有边的最少点个数,那么i的邻接点可选可不选(而不是一定不选,看注释样例就知道了),所以dp[i][0] += min(dp[i.son][

poj3659 Cell Phone Network(最小支配集-树形dp)

题目链接:点击打开链接 题目描述:给定一棵树,从中选取尽量少的点使每个点要么被选中,要么和被选中的点直接相连? 解题思路:树上的最小支配集,树形dp dp[i][0]:选中i作为支配集 dp[i][1]:不选i作为支配集,但其子节点覆盖了i dp[i][2]:不选i作为支配集,而且其子节点没有覆盖i 代码: #pragma comment(linker,"/STACK:1024000000,1024000000") #include <cstdio> #include &l

hdu 1151 或 poj 1422 二分图 最小点覆盖集

最小点覆盖集的裸题,只要“拆点建边”然后求出最大匹配,则:最小点覆盖集的大小 = 点数 - 最大匹配 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int N = 121; 7 const int M = 5000; 8 bool visit[N]; 9 int mark[N]; 10 int head[N]; 11 int

POJ2226 Muddy Fields(二分图最小点覆盖集)

题目给张R×C的地图,地图上*表示泥地..表示草地,问最少要几块宽1长任意木板才能盖住所有泥地,木板可以重合但不能盖住草地. 把所有行和列连续的泥地(可以放一块木板铺满的)看作点且行和列连续泥地分别作为XY部,每一块泥地看作边.这样就构造出了一个二分图. 那么,问题就是在这个二分图中就是选出最少的点覆盖所有的边,即二分图最小点覆盖集,而二分图最小点覆盖集=二分图最大匹配. 1 #include<cstdio> 2 #include<cstring> 3 #include<qu

Jewelry Exhibition(最小点覆盖集)

Jewelry Exhibition 时间限制: 1 Sec  内存限制: 64 MB提交: 3  解决: 3[提交][状态][讨论版] 题目描述 To guard the art jewelry exhibition at night, the security agency has decided to use a new laser beam system, consisting of sender-receiver pairs. Each pair generates a strip o

ACM/ICPC 之 机器调度-匈牙利算法解最小点覆盖集(DFS)(POJ1325)

//匈牙利算法-DFS //求最小点覆盖集 == 求最大匹配 //Time:0Ms Memory:208K #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; #define MAX 105 #define INF 0x3f3f3f3f int n,m,k; int gp[MAX][MAX]; bool sx[MAX],s

hdu 4514 并查集+树形dp

湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 4539    Accepted Submission(s): 816 Problem Description 随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,

Strategic game POJ - 1463 【最小点覆盖集】

Bob enjoys playing computer games, especially strategic games, but sometimes he cannot find the solution fast enough and then he is very sad. Now he has the following problem. He must defend a medieval city, the roads of which form a tree. He has to