PAT-1021 Deepest Root (25)

题目大意:给定一个图,判断是不是一棵包含全部顶点的树。如果是,找出所有的顶点按顺序输出,满足的条件为以该顶点为根的树拥有最大的深度;否则输出有几个连通块。

解题思路:用 vector 存储图,dfs 进行图的遍历搜索,可以获得最大深度;是否存在环 ( n 个点 n-1 条边,如果不是树,必是环(我的理解)),不存在环的条件可以用某点 dfs 除其父节点外其他相邻点均未被访问来判断。具体看代码细节(注:需要进行必要的剪枝操作,不然有一组样例会超时;除了剪枝,也可以利用 PAT 的一个小BUG,超时的那组对数据的敏感性不高,只要度为 1 都是结果,可以做个 n>1000 的判断,省去一些时间,不过这是投机取巧罢了,代码就不上了)。

剪枝操作也是险过。。。


题目链接:https://www.patest.cn/contests/pat-a-practise/1021

#include <iostream>            
#include <algorithm>            
#include <set>            
#include <map>            
#include <vector>            
#include <stack>            
#include <queue>            
#include <cmath>            
using namespace std;

vector<int > VV[10005];
bool visited[10005];
bool haveRing = false;//是否有回路标记 
int MaxL;//在单一的dfs中最大 
int MaxiumL = -1;//全局最大
 
void dfs(int s,int level)
{
  visited[s] = true;
  MaxL = max(MaxL,level); 
  int flag = 0;
  for(vector<int>::iterator it=VV[s].begin();it!=VV[s].end();++it)
  {
    if(visited[*it] == false)
      dfs(*it,level+1);
    else
      ++flag;
  }
  if(flag >= 2)//除父节点外有其他相邻节点被访问 
    haveRing = true;
  
}

int main(int argc, char** argv) {
  int n;
  cin >> n;
  for(int i=0;i<n-1;++i)
  {
    int tmp1,tmp2;
    cin >> tmp1 >> tmp2;
    VV[tmp1].push_back(tmp2);
    VV[tmp2].push_back(tmp1);
  }
  
  for(int i=1;i<=n;++i)
  {
    MaxL = -1;//每个循环初始化 
    fill(visited,visited+n+1,false);
    dfs(i,1);
    MaxiumL = max(MaxiumL,MaxL);
  }
  
  if(haveRing == false)
  {
    for(int i=1;i<=n;++i)
    {
		if(VV[i].size() <= 1)//剪枝。如果存在,则其度必小于等于1 
    	{
		    MaxL = -1;
		    fill(visited,visited+n+1,false);
		    dfs(i,1);
		    if(MaxL == MaxiumL)
		        cout<< i << endl; 
		} 
    }
  }
  else
  {
    int cnt = 0;
    fill(visited,visited+n+1,false);
    for(int i=1;i<=n;++i)
    {
      if(visited[i] == false)
      {
        ++cnt;//连通块计数 
        dfs(i,1);  
      }
    }
    cout<< "Error: " << cnt << " components";
  }
  return 0;
}

猜你喜欢

转载自blog.csdn.net/zhoujian_1943/article/details/79372818