树形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); }
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);
代码:
/******************************************** 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; }