1021. Deepest Root (25)

題目鏈接:https://www.patest.cn/contests/pat-a-practise/1021


題目大意:找出樹中能使樹的深度達到最大的根。


解題思路:

  • 定義深度優先DFS(int v,int high),該函數用來找離v點最遠點的集合
  • 先任取一點v,進行dfs找到離v點最遠的一部分點即爲集合set1,這些點是最終要求的點的子集。
  • 從set1中任選一點,在進行一次DFS,得到set2。
  • set1和set2的並集即爲最終所求。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> node[10001];//二維的vector,存儲每個結點相連的結點的下標
int visit[10001]={0};
int n;
int maxhigh=0;//最大高度
vector<int> tmp;//存儲距離dfs函數中的v點最深的點
void dfs(int v,int high){
    if(high>maxhigh){//找到更深的
        maxhigh=high;
        tmp.clear();//將之前的清除
        tmp.push_back(v);
    }
    else if(high==maxhigh){//距離相等的
        tmp.push_back(v);//直接保存
    }
    visit[v]=1;//標記爲已訪問
    for(int i=0;i<node[v].size();i++){
        if(visit[node[v][i]]==0){
            dfs(node[v][i],high+1);//遞歸地訪問與該節點臨接的頂點,深度加一
        }
    }
}
int main(int argc, char const *argv[])
{

    cin>>n;
    int a,b;
    int flag[10001]={0};//falg[i]=1表示結點i是最深的根節點之一
    for(int i=1;i<=n-1;i++){//輸入n-1條邊
        cin>>a>>b;
        node[a].push_back(b);
        node[b].push_back(a);
    }
    int cnt=0;//連通分量的個數
    for(int i=1;i<=n;i++){
        if(visit[i]==0){
            dfs(i,1);//第一次dfs
            cnt++;
        }
    }
    if(cnt>1)
        cout<<"Error: "<<cnt<<" components"<<endl;
    else{
        for(int i=0;i<tmp.size();i++){
            flag[tmp[i]]=1;
        }
        int start=tmp[0];//該點爲距離1最遠的點。
        tmp.clear();
        for(int i=1;i<=n;i++)
            visit[i]=0;
        dfs(start,1);//第二次dfs找距離start最遠的點
        tmp.push_back(start);
        for(int i=0;i<tmp.size();i++)
            flag[tmp[i]]=1;
        for(int i=1;i<=n;i++){
            if(flag[i]==1)
                cout<<i<<endl;
        }
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章