• HDU 1054 Strategic Game


    题目大意:一城堡的所有的道路形成一个n个节点的树,如果在一个节点上放上一个士兵,那么和这个节点相连的边就会被看守住,问把所有边看守住最少需要放多少士兵。 dproot[ i ] 表示以i为根的子树,在i上放置一个士兵,看守住整个子树需要多少士兵。

    掌握了一个图论知识:图的最小点覆盖=二分图的最大匹配

    #include <cstdio>
    #include <cstring>
    #include <vector>
    using namespace std;
    const int N=100000;
    int link[N],used[N];
    vector  v[N];
    int Dfs(int k){    
        for(int i=0;i<v[k].size();i++){
            int a=v[k][i];
            if(used[a]==0){
                used[a]=1;
                if(link[a]==-1||Dfs(link[a])){link[a]=k;return 1;}
            }
        }return 0;
    }
    int main(){
        int i,count,a,n,b,t,k;
        while(~scanf("%d",&n)){
            k=n;
            memset(link,-1,sizeof(link));
            for(i=0;i<n;i++)v[i].clear();
            while(n--){
                scanf("%d:(%d)",&a,&b);
                while(b--){
                    scanf("%d",&t);
                    v[a].push_back(t);
                    v[t].push_back(a);
     
                }
            }count=0;
            for(i=0;i<k;i++){
                memset(used,0,sizeof(used));
                if(Dfs(i))count++;
            }
            printf("%d
    ",count/2);
        }
        return 0;
    }

    树形Dp的效率明显比二分图匹配简单,而且编程复杂度低……

    #include <cstring> 
    #include <cstdio>
    #include <vector>
    #include <algorithm>
    using namespace std;
    const int N=1505;
    int tree[N],all[N];
    vector  v[N];
    void Dfs(int root,int father){
        tree[root]=1;
        int sum=0;
        for(int i=0;i<v[root].size();i++){
            int son=v[root][i];
            if(son!=father){
                Dfs(son,root);
                tree[root]+=all[son]; //覆盖当前点 
                sum+=tree[son]; //覆盖当前点的儿子节点 
            }
        }
        all[root]=min(sum,tree[root]); //DP取最优方案 
    }
    int main(){
        int i,count,a,n,b,t,k;
        while(~scanf("%d",&n)){
            k=n;
            for(i=0;i<n;i++)v[i].clear();
            while(n--){
                scanf("%d:(%d)",&a,&b);
                while(b--){
                    scanf("%d",&t);
                    v[a].push_back(t);
                    v[t].push_back(a);
     
                }
            }
            Dfs(0,0);
            printf("%d
    ",min(tree[0],all[0]));
        }
        return 0;
    }
    
  • 相关阅读:
    分布式数据Hive——HQL
    RPM包管理-rpm命令管理
    软件包管理简介
    网络命令
    压缩解压缩命令
    其他基本命令
    文件搜索命令
    权限管理命令
    文件处理命令
    系统分区
  • 原文地址:https://www.cnblogs.com/forever97/p/3624094.html
Copyright © 2020-2023  润新知