• Codefroces Gym 100781A(树上最长路径)


    http://codeforces.com/gym/100781/attachments

    题意:有N个点,M条边,问对两两之间的树添加一条边之后,让整棵大树最远的点对之间的距离最近,问这个最近距离是多少。

    思路:一开始看成只有两个连通块,后来才注意到是多个连通块。DFS搜树上最长路径。答案有三种:第一种是添加了边之后,树的最长路径还是原来子树的路径,第二种是对子树长度进行排序后,两个最长的距离分别除以2向上取整后加上1。第三种比较难注意到,就是第二第三长的分别除以2向上取整后加上2,因为可能隔着一条边之后比第一种情况更长了。

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstring>
     5 #include <string>
     6 #include <cmath>
     7 #include <queue>
     8 #include <vector>
     9 using namespace std;
    10 #define N 100010
    11 struct node
    12 {
    13     int v, nxt;
    14 }edge[N*2];
    15 int head[N], tot;
    16 bool vis[N];
    17 int ans[N];
    18 int l;
    19 
    20 void add(int u, int v)
    21 {
    22     edge[tot].v = v; edge[tot].nxt = head[u]; head[u] = tot++;
    23 }
    24 
    25 bool cmp(const int &a, const int &b)
    26 {
    27     return a > b;
    28 }
    29 
    30 int dfs(int u)
    31 {
    32     vis[u] = 1;
    33     int m1 = 0, m2 = 0;
    34     for(int i = head[u]; ~i; i = edge[i].nxt) {
    35         int v = edge[i].v;
    36         if(vis[v]) continue;
    37         int tmp = dfs(v) + 1;
    38         if(tmp > m1) {
    39             m2 = m1, m1 = tmp;
    40         } else if(tmp > m2) {
    41             m2 = tmp;
    42         }
    43     }
    44     if((m1 + m2) > l) l = m1 + m2;
    45     return m1;
    46 }
    47 
    48 int main()
    49 {
    50     int n, m;
    51     scanf("%d%d", &n, &m);
    52     memset(vis, 0, sizeof(vis));
    53     memset(head, -1, sizeof(head));
    54     memset(ans, 0, sizeof(ans));
    55     tot = 0;
    56     for(int i = 0; i < m; i++) {
    57         int u, v;
    58         scanf("%d%d", &u, &v);
    59         add(u, v); add(v, u);
    60     }
    61     int cnt = 0, res = 0;
    62     for(int i = 0; i < n; i++) {
    63         if(!vis[i]) {
    64             l = 0;
    65             dfs(i); //搜树上最长路径
    66             if(l > res) res = l; //第一种情况
    67             ans[cnt++] = l;
    68         }
    69     }
    70     sort(ans, ans + cnt, cmp);
    71     if(cnt > 1) res = max(res, (ans[0] + 1) / 2 + (ans[1] + 1) / 2 + 1); //第二种情况
    72     if(cnt > 2) res = max(res, (ans[1] + 1) / 2 + (ans[2] + 1) / 2 + 2); //第三种情况
    73     printf("%d
    ", res);
    74     return 0;
    75 }
  • 相关阅读:
    python错误信息 object is not subscriptable 的原因
    python join函数
    string的部分总结
    第k个非立方数(忘记哪里的题了)
    pandas 学习
    数学建模中 时间序列典型分解模型 matlab实现
    matlab三维画图学习 三次插值
    原型
    JavaScript
    js数组去重(多种写法)
  • 原文地址:https://www.cnblogs.com/fightfordream/p/5901085.html
Copyright © 2020-2023  润新知