• poj 2057 The Lost House 夜


    http://poj.org/problem?id=2057

    题意比较简单

    是典型的树 DP

    思路:

    先建树 然后一遍DFS求的每个节点的 访问一遍失败回来的总步数 和每个子树的叶子节点树

    再对每个节点后面的子节点按照优先级排序 就是确定先访问谁

    代码及其注释:

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<queue>
    #include<cmath>
    #include<stack>
    #include<algorithm>
    #define LL long long
    
    using namespace std;
    
    const int N=1005;
    
    struct node
    {
        int sum;
        struct tt *next;
    }mem[N];
    struct tt
    {
        int j;
        struct tt *next;
    };
    struct link
    {
        char c;
        int pre;//父节点
        int leafnum;//叶子节点数
        int backnum;//失败返回的步数
    }point[N];
    void build(int i,int j)
    {
        struct tt *t=new tt;
        t->j=j;
        t->next=mem[i].next;
        mem[i].next=t;
    }
    void Dele(int n)
    {
        struct tt *t;
        for(int i=1;i<=n;++i)
        {
            while(mem[i].next!=NULL)
            {
                t=mem[i].next;
                mem[i].next=t->next;
                delete t;
            }
        }
    }
    void mysort(int x)//按优先级排序
    {
        if(mem[x].next==NULL)
        return ;
        struct tt *t,*w;
        for(t=mem[x].next;t!=NULL;t=t->next)
        {
            for(w=t->next;w!=NULL;w=w->next)
            {
                if(point[t->j].leafnum*(point[w->j].backnum+2)<(point[t->j].backnum+2)*point[w->j].leafnum)
                {
                    swap(t->j,w->j);
                }
            }
        }
    }
    void Dfs1(int x)//求叶子节点数 和失败返回步数
    {
        struct tt *t;
        t=mem[x].next;
        point[x].leafnum=0;
        point[x].backnum=0;
        while(t!=NULL)
        {
            Dfs1(t->j);
            point[x].leafnum+=point[t->j].leafnum;
            point[x].backnum+=(2+point[t->j].backnum);
            t=t->next;
        }
        if(mem[x].next==NULL)
        {
            point[x].leafnum=1;
        }
        if(point[x].c=='Y')
        {
            point[x].backnum=0;
        }
    }
    void Dfssum(int x)//统计总和
    {
        if(mem[x].next==NULL)
        {
            mem[x].sum=0;return;
        }
        mem[x].sum=0;
        struct tt *t;
        t=mem[x].next;
        int itemp=0;
        while(t!=NULL)
        {
            Dfssum(t->j);
            mem[x].sum+=(itemp*point[t->j].leafnum+mem[t->j].sum);
            itemp+=(point[t->j].backnum+2);
            t=t->next;
        }
        mem[x].sum+=point[x].leafnum;
    }
    int main()
    {
           int n;
           while(scanf("%d",&n)!=EOF,n)
           {
               for(int i=1;i<=n;++i)
               {
                   scanf("%d %c",&point[i].pre,&point[i].c);
                   if(point[i].pre==-1)
                   continue;
                   build(point[i].pre,i);//建树
               }
               Dfs1(1);
               for(int i=1;i<=n;++i)
               mysort(i);//排序
               Dfssum(1);
               printf("%.4f\n",(1.0*mem[1].sum/point[1].leafnum));
               Dele(n);
           }
    }
    

      

  • 相关阅读:
    RMQ(非log2储存方法)
    2016年5月份学习记录
    NOIP200504循环
    膜拜acm大牛 虽然我不会这题,但是AC还是没有问题的~(转自hzwer)
    最长公共子序列的长度
    菜鸟,大牛和教主三者的区别(转自hzwer)
    NOIP201205Vigenère密码
    NOIP200503采药
    公路乘车
    NOIP200902分数线划定
  • 原文地址:https://www.cnblogs.com/liulangye/p/2604317.html
Copyright © 2020-2023  润新知