PTA 甲级1021Deepest Root
题目链接:1021
题目解析:
首先根据所给图是否存在多个子图(即连通分量问题),若不存在多个子图则找出最长路径的两个端点(即树的直径问题),最长路径可能有许多条。
解题思路:
对所给图每个点进行深度优先搜索,在搜索的过程中,给每个点设置id(其所属的子图),这样就能通过id的个数判断是否有多个子图。同时在搜索过程中直接找到每个点的最长路径。
代码如下:
#include<cstdio>
#include<vector>
#include<stack>
#include<algorithm>
#define MAX 10001
#define nil -1
using namespace std;
vector<int> G[MAX];
int n,d[MAX],id[MAX];
int c;
void dfs(int s){
int dis[n+1];
int color[n+1];
stack<int> s1;
for(int i=1;i<=n;i++){
dis[i]=-1;
}
s1.push(s);
dis[s]=0;
while(!s1.empty()){
int u=s1.top();
s1.pop();
for(int i=0;i<G[u].size();i++){
int t=G[u][i];
id[t]=c;
if(dis[t]==-1){
dis[t]=dis[u]+1;
s1.push(t);
}
}
}
d[s]=0;
for(int i=1;i<=n;i++){
d[s]=max(d[s],dis[i]);
}
}
int main(void){
c=0;
scanf("%d",&n);
for(int i=0;i<n-1;i++){
int s,t;
scanf("%d%d",&s,&t);
G[s].push_back(t);
G[t].push_back(s);
}
for(int i=1;i<=n;i++)
id[i]=nil;
id[1]=c;
for(int i=1;i<=n;i++){
if(id[i]==nil){
c++;
}
dfs(i);
}
if(c){
printf("Error: %d components",c+1);
return 0;
}
int *zd;
zd=max_element(d+1,d+n+1);
for(int i=1;i<=n;i++)
if(d[i]==*zd)
printf("%d\n",i);
return 0;
}