zoukankan      html  css  js  c++  java
  • 战略游戏(树形DP)

    洛咕

    题意:在一棵树的结点上放置最少数目的士兵,使得这些士兵能瞭望到所有的路.注意,某个士兵在一个结点上时,与该结点相连的所有边将都可以被瞭望到.

    分析:很经典的一道节点01型树上背包问题.对于每一个节点只有两种情况,选(1)或者不选(0).所以状态转移只有两种:

    (f[u][0]+=f[v][1]),若父节点u不选,则子节点v都要选.

    (f[u][1]+=min(f[v][0],f[v][1])),若父节点u被选了,则子节点v取最优情况.

    初始化(f[u][1]=1,f[u][0]=0).

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
       int s=0,w=1;char ch=getchar();
       while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
       while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
       return s*w;
    }
    int n,root;
    int visit[1505],f[1505][2];
    vector<int> q[1505];
    void dfs(int u){
        f[u][1]=1;f[u][0]=0;
        for(int i=0;i<q[u].size();i++){
    		int v=q[u][i];
    		dfs(v);
    		f[u][0]+=f[v][1];
    		f[u][1]+=min(f[v][0],f[v][1]);
        }
        return;
    }
    int main(){
        n=read();
        for(int i=1;i<=n;i++){
    		int num=read(),size=read();
    		for(int j=1;j<=size;j++){
    	    	int son=read();
    	    	q[num].push_back(son);
    	    	visit[son]=1;//标记是子节点
    		}//存边,根据个人习惯
        }
        for(int i=0;i<n;i++)//找根
        	if(!visit[i]){root=i;break;}
        dfs(root);
        printf("%d
    ",min(f[root][0],f[root][1]));
        return 0;
    }
    
    
  • 相关阅读:
    一个切换鼠标左右手的小工具
    聊一聊高并发高可用那些事
    PHP 笔记
    PHP 安装 XDebug
    php symfony/var-dumper 打印插件
    PHP字符串和数组
    ThinkPHP自定义分页模板
    匿名函数
    SQL优化工具
    spring cloud 服务容错保护
  • 原文地址:https://www.cnblogs.com/PPXppx/p/10543143.html
Copyright © 2011-2022 走看看