• Strategic game POJ


    //题意:就是你需要派最少的士兵来巡查每一条边。相当于求最少点覆盖,用最少的点将所有边都覆盖掉
    //题解:
    //因为这是一棵树,所以对于每一条边的两个端点,肯定要至少有一个点需要放入士兵,那么对于x->y这一条边
    //dp[x][0]=0 表示在x这一点上不放人士兵
    //dp[x][1]=1 表示在x这一个点上放入士兵
    //那么就有
    //dp[x][0]+=dp[y][1];
    //dp[x][1]+=min(dp[y][0],dp[y][1]);

    //注意这一道题不需要建立一个图,然后再去dfs,因为题目上就是按树从根到叶逐渐给出的。所以可以直接存
    //belong用来表示每一个点的层数,pre表示它的父亲节点

    第一次我是建了一个图去找dp,然后就MLE了

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<iostream>
     4 #include<algorithm>
     5 using namespace std;
     6 const int maxn=1500;
     7 struct edge
     8 {
     9     int v,next;
    10 }e[maxn];
    11 int cnt,head[maxn],dp[maxn][5];
    12 void add_edge(int x,int y)
    13 {
    14     e[cnt].v=y;
    15     e[cnt].next=head[x];
    16     head[x]=cnt++;
    17 }
    18 int n;
    19 void dfs(int x,int pre)
    20 {
    21     dp[x][0]=0;
    22     dp[x][1]=1;
    23     for(int i=head[x];i!=-1;i=e[i].next)
    24     {
    25         int to=e[i].v;
    26         //printf("%d %d
    ",x,to);
    27         if(to==pre)
    28         {
    29             //printf("**%d**%d
    ",x,to);
    30             continue;
    31         }
    32         dfs(to,x);
    33         dp[x][0]+=dp[to][1];
    34         dp[x][1]+=min(dp[to][1],dp[to][0]);
    35     }
    36 }
    37 int main()
    38 {
    39     while(~scanf("%d",&n))
    40     {
    41         memset(head,-1,sizeof(head));
    42         cnt=0;
    43         memset(dp,0,sizeof(dp));
    44         int x,y,sum,u,flag=0;
    45         for(int i=1;i<=n;++i)
    46         {
    47             scanf("%d:(%d)",&x,&sum);
    48 
    49             x++;
    50             if(flag==0)
    51             {
    52                 flag=1;
    53                 u=x;
    54             }
    55             while(sum--)
    56             {
    57                 scanf("%d",&y);
    58                 y++;
    59                 add_edge(x,y);
    60                 add_edge(y,x);
    61             }
    62         }
    63         //printf("%d**
    ",u);
    64         dfs(u,u);
    65         printf("%d
    ",min(dp[u][0],dp[u][1]));
    66     }
    67     return 0;
    68 }
    View Code

    正解:

     1 //题意:就是你需要派最少的士兵来巡查每一条边。相当于求最少点覆盖,用最少的点将所有边都覆盖掉
     2 //题解:
     3 //因为这是一棵树,所以对于每一条边的两个端点,肯定要至少有一个点需要放入士兵,那么对于x->y这一条边
     4 //dp[x][0]=0 表示在x这一点上不放人士兵
     5 //dp[x][1]=1 表示在x这一个点上放入士兵
     6 //那么就有
     7 //dp[x][0]+=dp[y][1];
     8 //dp[x][1]+=min(dp[y][0],dp[y][1]);
     9 
    10 //注意这一道题不需要建立一个图,然后再去dfs,因为题目上就是按树从根到叶逐渐给出的。所以可以直接存
    11 //belong用来表示每一个点的层数,pre表示它的父亲节点
    12 #include<stdio.h>
    13 #include<string.h>
    14 #include<iostream>
    15 #include<algorithm>
    16 using namespace std;
    17 const int maxn=1505;
    18 int belong[maxn],pre[maxn],dp[maxn][5],cnt;
    19 int n;
    20 void DP(int x,int index)
    21 {
    22     dp[x][0]=0;
    23     dp[x][1]=1;
    24     for(int i=1;i<=n;++i)
    25     {
    26         if(pre[i]==x)
    27         {
    28             DP(i,index+1);
    29             dp[x][0]+=dp[i][1];
    30             dp[x][1]+=min(dp[i][0],dp[i][1]);
    31         }
    32     }
    33 }
    34 int main()
    35 {
    36     while(~scanf("%d",&n))
    37     {
    38         memset(pre,0,sizeof(pre));
    39         memset(dp,0,sizeof(dp));
    40         memset(belong,0,sizeof(belong));
    41         cnt=0;
    42         int x,y,sum,u,flag=0;
    43         for(int i=1;i<=n;++i)
    44         {
    45             scanf("%d:(%d)",&x,&sum);
    46             x++;
    47             belong[x]=++cnt;
    48             if(flag==0)
    49             {
    50                 flag=1;
    51                 u=x;
    52             }
    53             cnt++;
    54             while(sum--)
    55             {
    56                 scanf("%d",&y);
    57                 y++;
    58                 pre[y]=x;
    59 //                add_edge(x,y);
    60 //                add_edge(y,x);
    61                 belong[y]=cnt;
    62             }
    63         }
    64         pre[u]=-1;
    65         DP(u,1);
    66         printf("%d
    ",min(dp[u][0],dp[u][1]));
    67     }
    68     return 0;
    69 }
    View Code
  • 相关阅读:
    分布式数据库中间件Mycat百亿级数据存储(转)
    大文本字符串滤重的解决方案(转)
    java处理大文本2G以上
    Mysql binlog详解
    varnish squid nginx比较
    java运行时内存分类
    redis rdb aof比较
    LeetCode 94 ——二叉树的中序遍历
    线性代数之——向量空间
    线性代数之——A 的 LU 分解
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/11663803.html
Copyright © 2020-2023  润新知