「
「
「动态规划
」
」
」第
4
4
4章 树形
D
P
(
DP(
DP(后
2
2
2题
)
)
)
目录:
C.最长距离
D.选课方案
C . C. C. 例题 3 3 3 最长距离
分析:
从每个点出发到达的最远距离 对于一个点的答案有 2 2 2种
- 向子节点走
- 向父节点走
第一遍
d
f
s
dfs
dfs找向子节点走的最远距离
第二遍
d
f
s
dfs
dfs找向父节点走的最远距离 但对于一个节点
x
x
x 最长距离可能是经过它的父节点
f
a
fa
fa然后向下
由于路径不能重复 当
x
x
x为
f
a
fa
fa向子节点走的最远节点时 要用次大值更新
x
x
x
也要每次更新次大值 更新完最大值 次大值就是更新前的最大值
s
m
a
x
d
i
s
smaxdis
smaxdis为次大值
m
a
x
d
i
s
maxdis
maxdis为最大值
CODE:
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e4+5;
int n;
struct node{
int to,next,dis;
}a[N<<1];
int head[N],tot,maxdis[N],smaxdis[N];
void add(int x,int y,int k)
{
a[++tot]=(node){y,head[x],k};
head[x]=tot;
}
void dfs(int x,int fa)
{
maxdis[x]=0;
smaxdis[x]=0;
for(int i=head[x];i;i=a[i].next)
{
int qwq=a[i].to;
if(qwq==fa) continue;
dfs(qwq,x);
if(maxdis[x]<=maxdis[qwq]+a[i].dis)
{
smaxdis[x]=maxdis[x];
maxdis[x]=maxdis[qwq]+a[i].dis;
}
else if(maxdis[qwq]+a[i].dis>smaxdis[x])
smaxdis[x]=maxdis[qwq]+a[i].dis;
}
}
void dfs2(int x,int fa,int len)
{
if(maxdis[fa]!=maxdis[x]+len)
{
if(maxdis[x]<=maxdis[fa]+len)
{
smaxdis[x]=maxdis[x];
maxdis[x]=maxdis[fa]+len;
}
else if(maxdis[fa]+len>smaxdis[x])
smaxdis[x]=maxdis[fa]+len;
}else
{
if(maxdis[x]<=smaxdis[fa]+len)
{
smaxdis[x]=maxdis[x];
maxdis[x]=smaxdis[fa]+len;
}
else if(smaxdis[fa]+len>smaxdis[x])
smaxdis[x]=smaxdis[fa]+len;
}
for(int i=head[x];i;i=a[i].next)
{
int qwq=a[i].to;
if(qwq==fa) continue;
dfs2(qwq,x,a[i].dis);
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
memset(head,0,sizeof(head));
tot=0;
for(int i=2;i<=n;i++)
{
int fa,dis;
scanf("%d%d",&fa,&dis);
add(i,fa,dis);
add(fa,i,dis);
}
dfs(1,0);
for(int i=head[1];i;i=a[i].next)
dfs2(a[i].to,1,a[i].dis);
for(int i=1;i<=n;i++)
printf("%d\n",maxdis[i]);
}
return 0;
}
D . D. D. 例题 4 4 4 选课方案
分析:
之前写过了……
b
l
o
g
blog
blog
l
i
n
k
link
link
把码风改了改
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=305;
int n,m,f[N][N],son[N][N],vis[N],tot[N],p[N][N];
void dp(int dep)
{
vis[dep]=1;
for(int i=0;i<tot[dep];i++)
{
int qwq=son[dep][i];
if(vis[qwq]) continue;
dp(qwq);
for(int j=m;j>=0;j--)
for(int k=j-1;k>=0;k--)
f[dep][j]=max(f[dep][j],f[qwq][k]+f[dep][j-k-1]+p[dep][qwq]);
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
int x,w;
scanf("%d%d",&x,&w);
p[x][i]=w;
son[x][tot[x]++]=i;
}
dp(0);
printf("%d",f[0][m]);
return 0;
}