1021.Deepest Root (25)

1021.Deepest Root (25)

pat-al-1021

2017-02-04

  • 考点:深搜dfs
  • 关于连通分量的计算:从任一点出发开始深搜,结束一次搜索后如果还有点没被访问到(即,可以进行多次搜索)说明连通分量不止一个,能进行几次搜索就有几个连通分量
  • 关于题目要求的找最长的路径的起始点,参考了:1021. Deepest Root (25)-PAT甲级真题。个人理解:第一次出发开始搜索(不管起始点是哪个节点)所找到的「当前」最长路径的终点(们),一定是「整个图」最长路径的的起始点,所以再以此为起始点去深搜,找到的「当前」最长路径的终点,也一定是要找的「整个图」最长路径的起始点(因为这是无向图嘛,起点亦是终点,终点亦是起点)。把这些点保存下来,就是要求的节点。还不能理解就自己在草稿纸上画一画。
  • 不能用数组来存储边了,会内存超限,要改用vector
  • 关于vector作为二维数组使用:要么声明时就声明为vector< vector< int> > e,搭配e.resize(n)来使用;要么声明时就给定大小vector< int> e[101],也可作为二维数组用。如果声明时是一维的,又没给定大小,就不能作为二维数组用。
  • 使用set是因为set能按从小到大的顺序去保存放进去的数,不用自己排序了
  • 练习了一下迭代器iterator的使用
/**
 * pat-al-1021
 * 2017-02-03
 * Cpp version
 * Author: fengLian_s
 */
#include<stdio.h>
#include<string>
#include<vector>
#include<set>
#define MAX 10001
#define INF 0x3f3f3f3f
using namespace std;
int n, visited[MAX];
vector<vector<int> > e;
int maxDepth = -1;
vector<int> v;
set<int> s;
void dfs(int id, int depth)
{
  visited[id] = 1;
  if(depth > maxDepth)
  {
    maxDepth = depth;
    v.clear();
    v.push_back(id);
  }
  else if(depth == maxDepth)
  {
    v.push_back(id);
  }
  for(int i = 0;i < e[id].size();i++)
  {
    if(visited[e[id][i]] == 0)
      dfs(e[id][i], depth+1);
  }
}
int main()
{
  freopen("in.txt", "r", stdin);
  scanf("%d", &n);
  e.resize(n+1);
  for(int i = 1;i < n;i++)
  {
    int node1, node2;
    scanf("%d%d", &node1, &node2);
    e[node1].push_back(node2);
    e[node2].push_back(node1);
  }
  int cnt = 0, s1;
  fill(visited, visited+MAX, 0);
  for(int i = 1;i <= n;i++)
  {
    if(visited[i] == 0)
    {
      dfs(i, 0);
      //printf("i = %d\n", i);
      cnt++;
      if(i == 1)
      {
        for(int j = 0;j < v.size();j++)
        {
          s.insert(v[j]);
          if(j == 0)
            s1 = v[j];
        }
      }
    }
  }
  if(cnt > 1)
    printf("Error: %d components\n", cnt);
  else
  {
    v.clear();
    fill(visited, visited+MAX, 0);
    dfs(s1, 0);
    for(int i = 0;i < v.size();i++)
      s.insert(v[i]);
    for(set<int>::iterator it = s.begin();it != s.end();it++)
      printf("%d\n", *it);
  }
  return 0;
}

-FIN-

# -*- coding: utf-8 -*- '''请在Begin-End之间补充代码, 完成BinaryTree类''' class BinaryTree: # 创建左右子树为空的根结点 def __init__(self, rootObj): self.key = rootObj # 成员key保存根结点数据项 self.leftChild = None # 成员leftChild初始化为空 self.rightChild = None # 成员rightChild初始化为空 # 把newNode插入到根的左子树 def insertLeft(self, newNode): if self.leftChild is None: self.leftChild = BinaryTree(newNode) # 左子树指向由newNode所生成的BinaryTree else: t = BinaryTree(newNode) # 创建一个BinaryTree类型的新结点t t.leftChild = self.leftChild # 新结点的左子树指向原来根的左子树 self.leftChild = t # 根结点的左子树指向结点t # 把newNode插入到根的右子树 def insertRight(self, newNode): if self.rightChild is None: # 右子树指向由newNode所生成的BinaryTree # ********** Begin ********** # self.rightChild = BinaryTree(newNode) # ********** End ********** # else: t = BinaryTree(newNode) t.rightChild = self.rightChild self.rightChild = t # ********** End ********** # # 取得右子树,返回值是一个BinaryTree类型的对象 def getRightChild(self): # ********** Begin ********** # return self.rightChild # ********** End ********** # # 取得左子树 def getLeftChild(self): # ********** Begin ********** # return self.leftChild # ********** End ********** # # 设置根结点的值 def setRootVal(self, obj): # 将根结点的值赋值为obj # ********** Begin ********** # self.key = obj # ********** End ********** # # 取得根结点的值 def getRootVal(self): # ********** Begin ********** # return self.key # ********** End ********** # # 主程序 input_str = input() nodes = input_str.split(',') # 创建根节点 root = BinaryTree(nodes[0]) # 插入左子树和右子树 if len(nodes) > 1: root.insertLeft(nodes[1]) if len(nodes) > 2: root.insertRight(nodes[2]) # 前三行输出:对创建的二叉树按编号顺序输出结点 print(root.getRootVal()) left_child = root.getLeftChild
最新发布
03-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值