树形DP算是一个自己领悟的算法,以前第一做用的DFS维护的树形DP题,那时候还不知道这个算法叫树形DP,
这是第二次做树形DP,是浙大月赛,秦牛开场38分钟就AC了(时间很囧),我敲了1个多小时,还不是很熟练
题意维护每个节点和其子树的最大三个值,还是很水的题
#include <cstdio>
#include <string.h>
#define max(a,b) (a)>(b)?(a):(b)
#define swap(a,b) if((a)>(b)){int (t)=(a);(a)=(b);(b)=(t);}
const int maxn=10010;
const int inf=1<<29;
int maxv[maxn][4];
struct node
{
int v;
node *next;
node (int a):v(a){};
};
node * List[maxn];
int ww[maxn];
bool Is_l[maxn],vis[maxn];
void dfs (int u)
{
int tmp1=ww[u],tmp2=-1,tmp3=-1,i,v,w,t1,t2,t3;
vis[u]=true;
if(Is_l[u]){ maxv[u][0]=ww[u]; return ;}
node *p=List[u];
for ( ; p!=NULL ; p=p->next)
{
v=p->v;
//printf("%d %d\n",v,u);
if(!vis[v])
{
dfs(v);
t1=maxv[v][0];
t2=maxv[v][1];
t3=maxv[v][2];
swap(t1,tmp1);
swap(t1,tmp2);
swap(t1,tmp3);
swap(t2,tmp2);
swap(t2,tmp3);
swap(t3,tmp3);
//printf("tmp=%d %d %d\n",tmp1,tmp2,tmp3);
//printf("max=%d %d %d\n",maxv[v][0],maxv[v][1],maxv[v][2]);
}
}
maxv[u][0]=tmp1;
maxv[u][1]=tmp2;
maxv[u][2]=tmp3;
}
void init (int x)
{
for (int i=0 ; i<x ; ++i)
{
List[i]=NULL;
Is_l[i]=true;
for (int j=0 ; j<3 ; ++j)
maxv[i][j]=-1;
vis[i]=false;
}
}
int main ()
{
int n,i,j,u,w,m,v;
//freopen("in.txt","r",stdin);
while (~scanf("%d",&n))
{
init(n);
node * tmp;
scanf("%d",&w);
ww[0]=w;
/* tmp=new node(-1,w);
tmp->next=NULL;
List[0]==NULL?List[0]=tmp:(tmp->next=List[0],List[0]=tmp);*/
for (i=1 ; i<n ; ++i)
{
scanf("%d%d",&u,&w);
tmp=new node(i);
ww[i]=w;
tmp->next=NULL;
List[u]==NULL?List[u]=tmp:(tmp->next=List[u],List[u]=tmp);
Is_l[u]=false;
}
dfs(0);
scanf("%d",&m);
for (i=0 ; i<m ; ++i)
{
scanf("%d",&v);
bool flag=true ;
for (j=0 ; j<3 ; ++j)
if(!(~maxv[v][j]))flag=false;
if(flag)
printf("%d %d %d\n",maxv[v][0],maxv[v][1],maxv[v][2]);
else printf("-1\n");
}
}
return 0;
}
后来的改进代码
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=10010;
const int inf=0x5fffffff;
int maxv[maxn][7];
struct Edge{
int v, next;
}edge[maxn];
int head[maxn], cnt;
int node[maxn];
void addedge (int u, int v)
{
edge[cnt].v=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
bool cmp(int a, int b)
{
return a>b;
}
void dfs (int u)
{
maxv[u][0]=node[u];
for (int p=head[u] ; ~p ; p=edge[p].next)
{
int v=edge[p].v;
dfs(v);
maxv[u][3]=maxv[v][0];
maxv[u][4]=maxv[v][1];
maxv[u][5]=maxv[v][2];
sort(maxv[u],maxv[u]+6,cmp);
}
}
void init ()
{
memset (head, -1, sizeof(head));
memset (maxv, -1, sizeof(maxv));
cnt=0;
}
int main ()
{
int n, m;
int v;
while (~scanf("%d",&n))
{
init();
scanf("%d",node+0);
for (int i=1 ; i<n ; ++i)
{
scanf("%d%d",&v,node+i);
addedge(v,i);
}
dfs(0);
scanf("%d", &m);
for (int i=0 ; i<m ; ++i)
{
scanf("%d", &v);
if(~maxv[v][2])
printf("%d %d %d\n",maxv[v][0], maxv[v][1], maxv[v][2]);
else printf("-1\n");
}
}
return 0;
}