您的位置:首页 > 其它

poj 2057 The Lost House

2012-07-23 07:31 405 查看
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
;
struct tt
{
int j;
struct tt *next;
};
struct link
{
char c;
int pre;//父节点
int leafnum;//叶子节点数
int backnum;//失败返回的步数
}point
;
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);
}
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: