树形dp,两次dfs
son1[u],节点u向下能访问到的最大深度
son2[u],节点u向下能访问到的次大深度
f[u],节点向上能访问到的最大深度
第一次dfs求得son数组
dfs(v,u);
if(son1[v]+1 > son1[u]){
son2[u] = son1[u];
son1[u] = son1[v]+1;
}
else{
son2[u] = max(son2[u],son1[v]+1);
}
第二次dfs根据son数组求得f数组
if(son1[v]+1==son1[u]){
f[v] = max(f[v],son2[u]+1);
}
else{
f[v] = max(f[v],son1[u]+1);
}
f[v] = max(f[v],f[u]+1);
dfs1(v,u);
这道题注意不要有重边,有重边的话,dfs的时候树就会被遍历不止一次是指数级别的,会t的
代码:
/********************************************
Author :Crystal
Created Time :
File Name :
********************************************/
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <climits>
#include <string>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
#include <cctype>
using namespace std;
typedef long long ll;
typedef pair<int ,int> pii;
#define MEM(a,b) memset(a,b,sizeof a)
#define CLR(a) memset(a,0,sizeof a);
const int inf = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
#define LOCAL
#define maxn 10005
int cnt = 0;
int dp[maxn];
int f[maxn];
int son1[maxn];
int son2[maxn];
int head[maxn],pnt[maxn],nxt[maxn];
int v1[maxn];
int v2[maxn];
void addedge(int u,int v){
pnt[cnt] = v;
nxt[cnt] = head[u];
head[u] = cnt++;
}
void dfs(int u,int f1){
for(int i=head[u];~i;i=nxt[i]){
int v = pnt[i];
if(v!=f1){
dfs(v,u);
if(son1[v]+1 > son1[u]){
son2[u] = son1[u];
son1[u] = son1[v]+1;
}
else{
son2[u] = max(son2[u],son1[v]+1);
}
}
}
}
void dfs1(int u,int f1){
for(int i=head[u];~i;i=nxt[i]){
int v = pnt[i];
if(v!=f1){
if(son1[v]+1==son1[u]){
f[v] = max(f[v],son2[u]+1);
}
else{
f[v] = max(f[v],son1[u]+1);
}
f[v] = max(f[v],f[u]+1);
dfs1(v,u);
}
}
}
int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
// freopen("out.txt","w",stdout);
#endif
int n;
while(scanf("%d",&n)!=EOF){
int a = 0;
int b = 0;
int nmax = -1;
int nmin = inf;
MEM(dp,-1);
MEM(son1,-1);
MEM(son2,-1);
MEM(f,-1);
MEM(head,-1);
cnt = 0;
for(int i=1;i<=n;i++){
int t;scanf("%d",&t);
for(int j=1;j<=t;j++){
int v;scanf("%d",&v);
addedge(i,v);
}
}
dfs(1,-1);
dfs1(1,-1);
for(int i=1;i<=n;i++){
dp[i] = max(f[i],son1[i]);
}
for(int i=1;i<=n;i++){
nmax = max(dp[i],nmax);
nmin = min(nmin,dp[i]);
}
for(int i=1;i<=n;i++){
if(dp[i]==nmax){
v1[a++] = i;
}
if(dp[i]==nmin){
v2[b++] = i;
}
}
sort(v1,v1+a);
sort(v2,v2+b);
printf("Best Roots :");
for(int i=0;i<b;i++){
printf(" %d",v2[i]);
}
printf("\n");
printf("Worst Roots :");
for(int i=0;i<a;i++){
printf(" %d",v1[i]);
}
printf("\n");
}
return 0;
}