pat 1021 Deepest Root

題目是要判斷圖是否都連接構成樹,求使樹高最大的所有的根,實際上求圖上兩點間最大距離。我的思路是依次取各點進行DFS,記下各點可達的最大深度,再在其中取最大值,若各點的最大深度等於該值,該點爲所求。若最大深度不等於n-1,則不是一棵樹,再用並查集判斷有幾部分。可能思路有問題,WA了N久。參考網上程序,發現樹的最長路徑其實有個很方便的求法。任取一個點x,求出距離x最遠的一個點y,然後求出距離y最遠的一個點z。y到z就是一條最長路徑。他是先用並查集判斷共有幾個部分,再bfs求距離,先任取一點開始bfs,得到最遠的葉節點,以此葉節點再bfs可得。

AC代碼:(用鄰接表,可以看下)

 

#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<algorithm>
#include<cstdlib>
#include<memory.h>
using namespace std;
const int NUM=10005;

int isVisit[NUM];
int flag,n;

int step=1;
int parent[NUM];

// void dfs(int src,int cId)
// {
// 	int i;
// 	isVisit[cId]=1;
// 	if(step>deep[src])
// 		deep[src]=step;
// 	for(i=1;i<=n;i++){
// 		if(isVisit[i]==0&&map[cId][i]==1){
// 			step+=1;
// 			dfs(src,i);
// 			isVisit[i]=0;
// 			step-=1;
// 
// 		}
// 
// 	}
// }

vector<int> map[NUM];//鄰接表
vector<int> ans;
int dis[NUM];
int bfs(int x)//廣搜,相當於獲得以1爲根的樹的最大深度
{
	queue<int> q;
	memset(isVisit,0,sizeof(isVisit));
	isVisit[x]=1;
	int maxv=0;
	q.push(x);
	while(!q.empty()){
		int v=q.front();
		q.pop();
		int i;
		if(dis[v]>maxv)
			maxv=dis[v];
		for(i=0;i<map[v].size();++i)
			if(!isVisit[map[v][i]]){
				isVisit[map[v][i]]=1;
				dis[map[v][i]]=dis[v]+1;//深度+1
				q.push(map[v][i]);
			}
	}
	return maxv;
}


int find(int x)
{
	int r=x;
	while(parent[r]!=r){
		r=parent[r];
	}
	return r;
}

void merge(int a, int b)
{
	int x=find(a);
	int y=find(b);
	if(x!=y)
		parent[y]=x;
}
int main()
{
	int a,b,i,sum;
	freopen("C:\\Documents and Settings\\Administrator\\桌面\\input.txt","r",stdin);

	cin>>n;
	for(i=1;i<=n;i++)
		parent[i]=i;
	for(i=0;i<n-1;i++){
		cin>>a>>b;
		map[a].push_back(b);
		map[b].push_back(a);
		merge(a,b);
	}
	

	sum=0;
	for(i=1;i<=n;i++){
		if(parent[i]==i)
			sum++;
	}

	if(sum>1){//有多個分支
		cout<<"Error: "<<sum<<" components"<<endl;

	} else {//若是樹,則求圖中兩點的最大距離樹的最長路徑,任取一個點x,求出距離x最遠的一個點y,然後求出距離y最遠的一個點z。y到z就是一條最長路徑。
		int maxv=bfs(1);
		for(i=1;i<=n;++i){//求出距離x最遠的一個點y
			if(dis[i]==maxv)
				ans.push_back(i);
		}
		maxv=bfs(ans[0]);//求出距離y最遠的一個點z
		for(i=1;i<=n;++i){
			if(dis[i]==maxv)
				ans.push_back(i);
		}

		sort(ans.begin(),ans.end());
		cout<<ans[0]<<endl;
		for(i=1;i<ans.size();++i)
			if(ans[i]!=ans[i-1])
				cout<<ans[i]<<endl;

	}



	return 0;

}


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章