题目大意:
给出一个图,看能不能看成一棵树,不能的话输出连通图个数,能的话求出以哪些节点为根可以得出最大直径。
输入:
顶点个数和顶点个数-1条边
输出:
不能的话输出连通图个数,能的话输出那些可以得出最大直径节点的根的编号。
思路:
采用dfs求解。用vector保存图,先随便从一个节点dfs看是否是一棵树,不是的话直接输出连通图个数结束程序,如果是树的话,遍历每个节点为树根看得出的直径是多少,保存那些直径最大的节点排序输出
代码:
#include<cstdio>
#include<vector>
#include<string.h>
#include<algorithm>
using namespace std;
int n;
vector<int> v[100];
vector<int> number;
bool visit[10005];
int maxheight;
int tempheight;
int com=1;
void dfs(int index,int level)
{
visit[index]=true;//标志当前节点已访问
if(level>tempheight)
tempheight=level;//dfs时更新最大直径
for(int i=0;i<v[index].size();i++)//遍历和当前节点相连的节点
{
if(visit[v[index][i]]==false)
dfs(v[index][i],level+1);
}
}
int main()
{
scanf("%d",&n);
int edge1,edge2;
for(int i=1;i<=n-1;i++)
{
scanf("%d %d",&edge1,&edge2);
v[edge1].push_back(edge2);
v[edge2].push_back(edge1);
}
bool flag=true;
dfs(1,1);
for(int j=1;j<=n;j++)//dfs一遍后,若还有未被访问的节点说明不是一棵树
{
if(visit[j]==false)
{
flag=false;
com++;
dfs(j,1);
}
}
if(flag==false)
{
printf("Error: %d components",com);
return 0;
}
tempheight=-1;
for(int i=1;i<=n;i++)//从每个结点出发dfs一边,探寻最大直径
{
memset(visit,0,sizeof(visit));
dfs(i,1);
if(tempheight>maxheight)//若有更大的直径,则更新
{
maxheight=tempheight;
number.clear();//number数组保存可以得到最大直径的节点,若找到了更大的则清空,然后放入当前节点
number.push_back(i);
}
else if(tempheight==maxheight)
{
number.push_back(i);
}
tempheight=-1;
}
sort(number.begin(),number.end());
for(int i=0;i<number.size();i++)
{
printf("%d\n",number[i]);
}
return 0;
}