PAT甲级 1021 Deepest Root (25 分)(非并查集)
大佬们和算法笔记都给出了并查集的解法,而我在复习数据结构时,由于考纲不作要求而没有复习相关内容,故采用了自己的解法。
关键步骤:如何判断所给的图是否为树。
由于N个结点,N-1条边,故假设输入的图是树,从任意节点开始dfs都应该能完成遍历,否则题目转为计算图的连通块数。
不过并查集还是要找时间好好学一下理论和实现的。
代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
int n;
int now;
int Max = 0;
int count = 0;
vector<int>G[10001];
int p[10001] = { 0 };
bool vis[10001];
void dfs(int v,int depth)
{
vis[v] = true;
bool flag = false;
for (int i = 0;i < G[v].size();i++)
{
if (vis[G[v][i]] == false)
{
flag = true;
dfs(G[v][i], depth + 1);
}
}
if (flag == false)
{
if (depth > p[now])
{
p[now] = depth;
if (p[now] > Max)
Max = p[now];
}
}
}
int main()
{
scanf("%d", &n);
for (int i = 0;i < n-1;i++)
{
int a, b;
scanf("%d%d", &a, &b);
G[a].push_back(b);
G[b].push_back(a);
}
int block = 1;
bool iscon = true;
for (int i = 1;i <= n && iscon;i++)
{
now = i; //现在的起始点
memset(vis, false, sizeof(vis));
dfs(i, 0);
for (int i = 1;i <= n;i++)
{
if (vis[i] == false)//有没访问到的点说明不是树,开始计算连通块数
{
for (int j = i;j <= n;j++)
{
if (vis[j] == false)
{
dfs(j, 0);
block++;
}
}
iscon = false;
break;
}
}
}
if (!iscon)
{
printf("Error: %d components", block);
}
else
{
for (int i = 1;i <= n;i++)
{
if (p[i] == Max)
{
printf("%d\n", i);
}
}
}
}