POJ 1463 Strategic game (树形DP,放置点覆盖边)

来源:互联网 发布:淘宝货款 编辑:程序博客网 时间:2024/04/16 15:11

题意:给你一颗n个节点的树,在某一个节点上放置一个兵则可以守住与它相邻的边。问最少放置多少个兵才可以看守住所有的边。

#include<cstdio>#include<algorithm>#include<cstring>using namespace std;struct Edge { int v, next; } edge[3000];int head[3000], E;int n, vist[3000];int dproot[3000], total[3000];void add_edge(int u, int v){    edge[E].v = v;    edge[E].next = head[u];    head[u] = E++;}void deal(int u, int father){    if(vist[u]) return;    if(head[u] == -1)    {        total[u] = 0; //看住子树上所有边所需的兵数(根上放兵或者不放兵均可)        dproot[u] = 1; //根上放兵,看住子树上所有边        vist[u] = true;        return;    }    int i, v, sumTotal = 0, sumDp = 0;    for(i = head[u]; i != -1; i = edge[i].next)    {        v = edge[i].v;        if(v == father) continue;        if(!vist[v]) deal(v, u);        sumTotal += total[v];        sumDp += dproot[v];    }    dproot[u] = min(sumTotal, sumDp) + 1;    total[u] = min(sumDp, dproot[u]);    vist[u] = true;}int main(){    int node_id, node_num, adj_id;    while(scanf("%d",&n) != EOF)    {        E = 0;        memset(head,-1,sizeof(head));        memset(vist,0,sizeof(vist));        for(int i = 0; i < n; i++)        {            scanf("%d:(%d)", &node_id, &node_num);            while(node_num--)            {                scanf("%d",&adj_id);                add_edge(node_id, adj_id);                add_edge(adj_id, node_id);            }        }        deal(0, -1);        printf("%d\n",total[0]);    }    return 0;}


原创粉丝点击