1、http://acm.timus.ru/problem.aspx?space=1&num=1056
2、题目大意;
有n台计算机相连,已知1是根节点,现在要求的是谁是这个网络中的中心?
就是求每个点到其他点的最远距离中的最小距离的点
我们首先得求出每个点到其他点的最大距离来,然后找出这里边最小的距离对应的点是哪个
我们可以用两遍dfs求出来,
第一遍dfs,更新出每个结点的最远距离
第二次dfs,更新子节点是否可以通过自己的父节点可以到达更远的点
用dp[i][1]表示i点的最大值,dp[i][0]表示i点的次大值
最后只需要将dp[i][1]中最小的那个i值输出即可,可能不止一个
3、AC代码:
#include<stdio.h> #include<vector> #include<string.h> #include<algorithm> using namespace std; #define N 10005 #define INF 0x7fffffff vector<int> adj[N*2]; int visit[N]; int dp[N][2],ans; //dp[i][1]记录i点的最大值,dp[i][0]记录i点的次大值 void dfs1(int u) { visit[u]=1; for(int i=0; i<adj[u].size(); i++) { int v=adj[u][i]; if(visit[v]==0) { dfs1(v); if(dp[v][1]+1>dp[u][1]) { dp[u][0]=dp[u][1]; dp[u][1]=dp[v][1]+1; } else if(dp[v][1]+1>dp[u][0]) { dp[u][0]=dp[v][1]+1; } } } } void dfs2(int u) { visit[u]=1; for(int i=0; i<adj[u].size(); i++) { int v=adj[u][i]; //更新子节点的最大值和次大值 if(visit[v]==0) { int tmp;//如果v在父节点的最大链上,tmp=次大值+1 if(dp[u][1]==dp[v][1]+1) tmp=dp[u][0]+1; else tmp=dp[u][1]+1; if(tmp>dp[v][1]) { dp[v][0]=dp[v][1]; dp[v][1]=tmp; } else if(tmp>dp[v][0]) { dp[v][0]=tmp; } if(ans>dp[v][1]) ans=dp[v][1]; dfs2(v); } } } int main() { int n,a; scanf("%d",&n); for(int i=2; i<=n; i++) { scanf("%d",&a); adj[i].push_back(a); adj[a].push_back(i); } ans=INF; memset(visit,0,sizeof(visit)); dfs1(1); memset(visit,0,sizeof(visit)); dfs2(1); for(int i=1;i<=n;i++) { if(dp[i][1]==ans) printf("%d ",i); } printf("\n"); return 0; }