luogu#P2016 战略游戏

Posted nent

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu#P2016 战略游戏相关的知识,希望对你有一定的参考价值。

题意:

给出一棵有 (N) 个节点的树,节点编号 (0) ~ (N-1) 。如果在一个节点上放置一个士兵,那么该节点及与该节点相连的所有节点都可以被瞭望到。求瞭望到所有节点所需的最少的士兵数。

解法:

树形dp

(f[i][j]) = 节点 (i) 选((j=1))不选((j=0))的最少需要的士兵

因为对于一个节点 (i) ,如果它不选,那么必须选与它相连的点的其中一个,则:

f[x][1]+=min(f[v][0],f[v][1]); //设v是与x相邻的点
f[x][0]+=f[v][1];

因为没有给出树根,所以要手动求出。

感觉跟没有舞会的上司差不多,居然还是一道蓝题

#include<iostream>
#define N 1505
using namespace std;
struct Edge{int next,to;}edge[N<<1];
int n_e,head[N],n,root;
int f[N][2];
bool rt[N];

void dp(int x);
void addedge(int from,int to);
void init();
int main()
{
    init();
    dp(root);
    cout<<min(f[root][1],f[root][0]);
    
    return 0;
}
void init()
{
    cin>>n;
    for(int i=0;i<n;i++)
    {
        int id,num,v;
        cin>>id>>num;
        f[i][1]=1;
        for(int j=0;j<num;j++)
        {
            cin>>v;
            rt[v]=1;
            addedge(id,v);
        }
    }
    for(int i=0;i<n;i++)
        if(!rt[i])
        {
            root=i;
            break;
        }
}
void addedge(int from,int to)
{
    edge[++n_e].next=head[from];
    edge[n_e].to=to;
    head[from]=n_e;
}
void dp(int x)
{
    for(int i=head[x];i;i=edge[i].next)
    {
        int v=edge[i].to;
        dp(v);
        f[x][1]+=min(f[v][1],f[v][0]);
        f[x][0]+=f[v][1];
    }   
}

以上是关于luogu#P2016 战略游戏的主要内容,如果未能解决你的问题,请参考以下文章

luogu P2016 战略游戏 树形dp

luogu P3345 [ZJOI2015]幻想乡战略游戏(点分树)

luogu P3345 [ZJOI2015]幻想乡战略游戏 |动态点分治

[Luogu3345][ZJOI2015]幻想乡战略游戏

luogu P2825 [HEOI2016/TJOI2016]游戏

Luogu4606 SDOI2018 战略游戏 圆方树虚树链并