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);
       }
}

  

原文地址:https://www.cnblogs.com/liulangye/p/2604317.html