• hdu 1054 Strategic Game 夜


    http://acm.hdu.edu.cn/showproblem.php?pid=1054

    树形DP 主要是把思路屡清楚

    选个根结点进行向下搜 每个点都有两种可能 放士兵还是不放

    防止重复搜索就可以

    #include<iostream>
    #include<string>
    #include<string.h>
    #include<queue>
    #include<math.h>
    #include<stdio.h>
    #include<algorithm>
    #include<map>

    using namespace std;
    const int N=2000;
    int yans[N];//此点放士兵 以此点为根结点的树的放士兵最小值
    int nans[N];//此点不放士兵 以此点为根结点的树的放士兵最小值
    bool had[N];//建的链表为双向 所以不能回搜 用作标记
    struct node
    {
        struct tt *next;
    }mem[N];
    struct tt
    {
        struct tt *next;
        int k;
    };
    inline void build(int i,int j)//建邻接表
    {
        struct tt *t=new tt;
        t->k=j;
        t->next=mem[i].next;
        mem[i].next=t;
    }
    void freee(int n)//释放空间
    {
        struct tt *t;
        for(int i=0;i<n;++i)
        {
            while(mem[i].next!=NULL)
            {
                t=mem[i].next;
                mem[i].next=t->next;
                delete(t);
            }
        }
    }
    int ydp(int x);
    int ndp(int x)
    {
        if(nans[x]!=-1)//防止重复
        return nans[x];
        struct tt *t=mem[x].next;
        nans[x]=0;//此点不放
       while(t!=NULL)
       {
          if(!had[t->k])
          {
              had[t->k]=true;
              nans[x]+=ydp(t->k);//此点不放 下边的点必须放
              had[t->k]=false;
          }
          t=t->next;
       }
       return nans[x];
    }
    int ydp(int x)
    {
        if(yans[x]!=-1)
        return yans[x];
       struct tt *t=mem[x].next;
       yans[x]=1;//此点放
       while(t!=NULL)
       {
           if(!had[t->k])
           {
               had[t->k]=true;
               yans[x]+=min(ydp(t->k),ndp(t->k));//此点放 下边的点可放 可不放 取最小
               had[t->k]=false;
           }
          t=t->next;
       }
       return yans[x];
    }
    int main()
    {

        int n;
        while(scanf("%d",&n)!=EOF)
        {
            int i,j,m;
            for(int l=0;l<n;++l)
            {
                 scanf("%d",&i);
                 getchar();getchar();
                 scanf("%d",&m);
                 getchar();
                 while(m--)
                 {
                     scanf("%d",&j);
                     build(i,j);
                     build(j,i);
                 }
            }
            memset(yans,-1,sizeof(yans));
            memset(nans,-1,sizeof(nans));
            memset(had,false,sizeof(had));
            had[0]=true;
            printf("%d\n",min(ydp(0),ndp(0)));//以0为根结点 取最小
            freee(n);
        }
        return 0;
    }

  • 相关阅读:
    Codeforces Round #567 (Div. 2) B. Split a Number
    es界面的分组,求平均值的操作
    es界面的查询命令
    es界面的crud
    WebStorm中自定义文档注释模板
    Vue 正确理解mounted、beforeUpdate、updated三个钩子函数的关系
    oracle分析函数
    vue中时间格式的处理
    vue-router params和query的区别
    vue中的深拷贝理解和实现
  • 原文地址:https://www.cnblogs.com/liulangye/p/2465386.html
Copyright © 2020-2023  润新知