1. 程式人生 > >PAT 1021.Deepest Root

PAT 1021.Deepest Root

這道題目好像發了第三次的部落格了額 題目大意:一個連通的並且無環的圖可以認為是一棵樹。給定一個圖,要求輸出能夠讓樹的高度最大的節點的編號。如果這樣的節點不唯一,從小到大輸出;如果不存在,輸出圖的連通分量的個數。

因為N可以達到104的數量級,所以用鄰接矩陣的話會超記憶體。

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <vector>
#include <string.h>
using namespace std;

const int maxn =
10010; vector<int> G[maxn]; bool isroot[maxn]; int father[maxn]; int findfather(int x) { int a =x; while(father[x]!=x){ x=father[x]; } while(father[a]!=a){ int z = a; father[z] = x; a=father[a]; } return x; } void Union(int a,int b) { int
aa = father[a]; int bb = father[b]; if(aa!=bb) father[aa]=bb; } void init(int n) { for(int i=1;i<=n;i++) father[i]=i; } int calblock(int n) { int block = 0; for(int i=1;i<=n;i++) isroot[findfather(i)]=true; for(int i =1;i<=n;i++) block+
=isroot[i]; return block; } int maxh = 0; vector<int> tmp,ans; void dfs(int u ,int height, int pre) { if(height>maxh) { tmp.clear(); tmp.push_back(u); maxh=height; } else if(height = maxh) { tmp.push_back(u); } for(int i=0;i<G[u].size();i++) { if(G[u][i]==pre) continue; dfs(G[u][i],height+1,u); } } int main() { int a,b,n; scanf("%d",&n); init(n); for(int i=1;i<n;i++) { scanf("%d%d",&a,&b); G[a].push_back(b); G[b].push_back(a); Union(a,b); } int block = calblock(n); if(block!=1) printf("Error: %d components\n", block); else { dfs(1,1,-1); ans = tmp; dfs(ans[0],1,-1); for(int i=0;i<tmp.size();i++) ans.push_back(tmp[i]); sort(ans.begin(),ans.end()); printf("%d\n",ans[0]); for(int i=1;i<ans.size();i++) if(ans[i]!=ans[i-1]) printf("%d\n",ans[i]) } return 0; }