• NOIP2017-清北学堂国庆模拟1-Tyvj4865 天天和树


    原题
    树的直径。严谨的证明还没搞懂。
    或许三次BFS可以写个templete缩短代码?

    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int MaxN = 1e5;
    
    struct node {
      int vID;
      node *nx;
      node(): 
        vID(-1), nx(NULL) {}
      node(int init_vID, node* init_nx): 
        vID(init_vID), nx(init_nx) {}
    };
    node *arc[MaxN];
    
    node *newedge; 
    void add_edge(int x, int y) {
      newedge = new node(y, arc[x]);
      arc[x] = newedge;
      newedge = new node(x, arc[y]);
      arc[y] = newedge;
    }
    
    bool mark[MaxN];
    int q1[MaxN], from[MaxN]; 
    struct q2_ele {
      int vID, dist;
    }q2[MaxN];
    
    int main() {
      freopen("tree.in", "r", stdin);
      freopen("tree.out", "w", stdout);
      int n, i, x, y;
      scanf("%d", &n);
      for (i = 1; i < n; i++) {
        scanf("%d%d", &x, &y);
        x--; y--;
        add_edge(x, y);
      }
      
      //第一遍:找直径的一个端点
      int head, tail, u, s, curr;
      q1[0] = 0;
      mark[0] = true;
      for (head = 0, tail = 1; head != tail; head++) {
        curr = q1[head];
        for (node *adj = arc[curr]; adj != NULL; adj = adj->nx)
          if (!mark[adj->vID]) {
            mark[adj->vID] = true;
            q1[tail] = adj->vID;
            tail++;
          }
        if (head + 1 == tail)
          s = curr;
      }
      
      //第二遍:找出直径上的所有点
      int t, max_dist, curr_vID, curr_dist;
      memset(mark, false, sizeof(mark));
      q2[0] = (q2_ele) {s, 0};
      t = s; max_dist = 0;
      mark[s] = true;
      for (head = 0, tail = 1; head != tail; head++) {
        curr_vID = q2[head].vID; curr_dist = q2[head].dist;
        for (node *adj = arc[curr_vID]; adj != NULL; adj = adj->nx)
          if (!mark[adj->vID]) {
            mark[adj->vID] = true;
            q2[tail] = (q2_ele) {adj->vID, curr_dist + 1};
            from[adj->vID] = curr_vID;
            tail++;
          }
        if (curr_dist > max_dist) {
          t = curr_vID;
          max_dist = curr_dist;
        }
      }
      
      //第三遍:找到距离路径最远的结点
      int ans;
      memset(mark, false, sizeof(mark));
      for (i = t, tail = 0; i != s; i = from[i], tail++) {
        q2[tail] = (q2_ele) {i, 0};
        mark[i] = true;
      }
      mark[s] = true;
      for (head = 0; head != tail; head++) {
        curr_vID = q2[head].vID; curr_dist = q2[head].dist;
        for (node *adj = arc[curr_vID]; adj != NULL; adj = adj->nx)
          if (!mark[adj->vID]) {
            mark[adj->vID] = true;
            q2[tail] = (q2_ele) {adj->vID, curr_dist + 1};
            tail++;
          }
        if (head + 1 == tail)
          ans = curr_dist;
      }
      
      printf("%d
    ", ans);
      return 0;
    }
    
  • 相关阅读:
    CentOS6.0/RedHat Server 6.4安装配置过程 详细图解!
    关于Haproxy安装和配置:负载配置【haproxy.cfg】问题记录
    菜鸟学习Struts——bean标签库
    2013——2014总结
    高效程序员的45个习惯读书 ——敏捷开发修炼之道笔记之态度决定一切
    Hive深入浅出
    Java从入门到精通——调错篇之SVN 出现 Loced错误
    考试系统优化——准备工作
    深入解析:分布式系统的事务处理经典问题及模型(转载分享)
    黑客攻击 UVa11825
  • 原文地址:https://www.cnblogs.com/P6174/p/7545634.html
Copyright © 2020-2023  润新知