鏈接:https://pintia.cn/problem-sets/994805342720868352/problems/994805482919673856
題意:n個點n-1條邊,判斷是否是棵樹? 如果是,按字典序輸出節點編號(以該點爲根,深度最大);否則,輸出有幾個連通塊。
思路:首先,是否爲樹,用並查集判斷。至於找出符合要求的點,可以用暴力PTA測評姬真給力。,下面說一下宇宙無敵小汪汪的思路。類似於樹的直徑求法,先以1爲根節點,找到深度最深的幾個點,然後,以其中一個點爲根,找最深的點。注意去重,用set存一下好了。
1、暴力
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
using namespace std;
const int N = 1e4+10;
vector <int> g[N],dep[N];
int n;
int deep[N],f[N],u,v,num,high,h;
set<int> s;
set<int>::iterator it;
void init()
{
high=1,num=0;
for(int i=1;i<=n;i++)
f[i]=i;
return ;
}
int getf(int x){ return x==f[x]?x:f[x]=getf(f[x]); }
void merge(int u,int v)
{
int fu=getf(u),fv=getf(v);
if(fu!=fv)
f[fu]=fv;
}
void dfs(int u)
{
high=max(high,deep[u]);
for(int i=0;i<g[u].size();i++)
{
v=g[u][i];
if(deep[v]) continue;
deep[v]=deep[u]+1;
dfs(v);
}
}
int main(void)
{
cin>>n;
init();
for(int i=1;i<n;i++)
{
cin>>u>>v;
g[u].pb(v);
g[v].pb(u);
merge(u,v);
}
for(int i=1;i<=n;i++)
if(getf(i)==i) num++;
if(num>1)
{
printf("Error: %d components\n",num);
return 0;
}
h=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++) deep[j]=0;
high=1,deep[i]=1;
dfs(i);
h=max(h,high);
dep[high].pb(i);
}
for(int i=0;i<dep[h].size();i++)
printf("%d\n",dep[h][i]);
return 0;
}
2、
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
using namespace std;
const int N = 1e4+10;
vector <int> g[N],dep[N];
int n;
int deg[N],deep[N],f[N],u,v,num,high,st;
set<int> s;
set<int>::iterator it;
void init()
{
high=1,num=0;
for(int i=1;i<=n;i++)
f[i]=i;
return ;
}
int getf(int x){ return x==f[x]?x:f[x]=getf(f[x]); }
void merge(int u,int v)
{
int fu=getf(u),fv=getf(v);
if(fu!=fv)
f[fu]=fv;
}
void dfs(int u)
{
high=max(high,deep[u]);
for(int i=0;i<g[u].size();i++)
{
v=g[u][i];
if(deep[v]) continue;
deep[v]=deep[u]+1;
dep[deep[v]].pb(v);
dfs(v);
}
}
int main(void)
{
cin>>n;
init();
for(int i=1;i<n;i++)
{
cin>>u>>v;
deg[u]++,deg[v]++;
g[u].pb(v);
g[v].pb(u);
merge(u,v);
}
for(int i=1;i<=n;i++)
if(getf(i)==i) num++;
if(num>1)
{
printf("Error: %d components\n",num);
return 0;
}
deep[1]=1,dep[1].pb(1),dfs(1);
for(int i=0;i<dep[high].size();i++) s.insert(dep[high][i]);
st=dep[high][0];
s.insert(st);
for(int i=1;i<=high;i++) dep[i].clear();
high=1;
for(int i=1;i<=n;i++) deep[i]=0;
deep[st]=1,dep[1].pb(st),dfs(st);
for(int i=0;i<dep[high].size();i++)
s.insert(dep[high][i]);
for(it=s.begin();it!=s.end();it++)
cout<<(*it)<<endl;
return 0;
}