zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    Java 连oracle 12C 起步
    powershell excel 导入 sqlserver
    移动端适配方案(上)
    ie7兼容问题
    node学习第三天(2)
    node学习第三天(1)
    HTMl5的sessionStorage和localStorage的一些区别
    html5+css3实战之-幽灵按钮
    node.js理论知识梳理
    node.js学习第二天
  • 原文地址:https://www.cnblogs.com/forever97/p/3624094.html
Copyright © 2011-2022 走看看