一道树形dp的裸题(然而第一眼就是暴力)
暴力思想所有的最长链都过1然后1上走dfs(居然能拿50)
50分代码
#include <cstdio>
#include <algorithm>
#define MAXN 100010
using namespace std;
int n, ans, maxx;
int ce[MAXN], r[MAXN], l[MAXN];
int read() {
int f = 1, k = 0;
char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') {
f = -1;
}
c = getchar();
}
while(c >= '0' && c <= '9') {
k = k * 10 + c - '0';
c = getchar();
}
return f * k;
}
void dfs(int a, int c) {
ce[a] = c;
if(r[a]) dfs(r[a], c + 1);
if(l[a]) dfs(l[a], c + 1);
}
void fan(int a) {
if(r[a]) fan(r[a]);
if(l[a]) fan(l[a]);
maxx = max(ce[a], maxx);
}
int main() {
n =read();
for(int i = 1; i <= n; i ++) {
l[i] = read(), r[i] = read();
}
dfs(1, 0);
maxx = 0;
fan(r[1]);
ans += maxx;
maxx = 0;
fan(l[1]);
ans += maxx;
printf("%d", ans);
return 0;
}
然后滚去想树形dp了(缩)
coedvs良心的给出了1(真诚脸), f记录了以当前这个点为一端时的最长长度
f[a]=max(f[r[a]],f[l[a]])+1
ans=max(ans,f[r[a]]+f[l[a]]+1)
#include <cstdio>
#include <algorithm>
#define MAXN 100010
using namespace std;
int n, r[MAXN], ans, l[MAXN];
int f[MAXN];
int read() {
int f = 1, k = 0;
char c = getchar();
while(c > '9' || c < '0') {
if(c == '-') {
f = -1;
}
c = getchar();
}
while(c >= '0' && c <= '9') {
k = k * 10 + c - '0';
c = getchar();
}
return f * k;
}
void dp(int a) {
f[a] = 1;
if(l[a] == 0 && r[a] == 0) return;
if(r[a]) dp(r[a]);
if(l[a]) dp(l[a]);
f[a] = max(f[r[a]], f[l[a]]) + 1;
ans = max(f[r[a]] + f[l[a]] + 1, ans);
}
int main() {
n = read();
for(int i = 1; i <= n; i ++) {
l[i] = read(), r[i] = read();
}
dp(1);
ans--;
printf("%d", ans);
return 0;
}