dfs和求连通分量。可以用并查集统计连通分量个数。对每一个结点dfs,求出以它作为结点的树的高度。vector真是非常好用的东西,用来存稀疏图再好不过,一开始用数组和动态分配都会内存溢出,用vector一下子就解决。然后就是dfs要注意进栈出栈。
#include <iostream> #include <algorithm> #include <vector> using namespace std; int *set,N,stack[10001],sp=-1,maxpath=-1; bool *visit; vector<int>root; vector<vector<int>>G; int Find(int n) { if(set[n]<0)return n; else return Find(set[n]); } void UnionBySize(int n1,int n2) { int r1=Find(n1),r2=Find(n2); if(r1==r2)return ; if(set[r1]<=set[r2]) { set[r1]+=set[r2]; set[r2]=r1; } else { set[r2]+=set[r1]; set[r1]=r2; } return ; } void dfs(int S,int u) { stack[++sp]=u; visit[u]=true; if(sp+1>maxpath) { maxpath=sp+1; root.clear(); root.push_back(S); set[S]=0; } else if(sp+1==maxpath) { if(set[S]!=0)root.push_back(S); set[S]=0; } for(vector<int>::iterator v=G[u].begin();v!=G[u].end();v++) { if(visit[*v]==false) dfs(S,*v); } sp--; return ; } int main() { cin>>N; G.resize(N+1); set=new int[N+1]; fill(set,set+N+1,-1); visit=new bool[N+1]; fill(visit,visit+N+1,false); for(int i=1;i<=N-1;i++) { int n1,n2; cin>>n1>>n2; G[n1].push_back(n2); G[n2].push_back(n1); UnionBySize(n1,n2); } for(int i=1,cnt=0;i<=N;i++) { if(set[i]<0)cnt++; if(i==N&&cnt>1) { cout<<"Error: "<<cnt<<" components"; return 0; } } for(int u=1;u<=N;u++) { fill(visit,visit+N+1,false); dfs(u,u); } for(vector<int>::iterator p=root.begin();p!=root.end();p++) { cout<<*p<<endl; } }