题目大意:有n个点,m条边,形成2颗以上的树,为了加上若干条边使得整个图连通后任意两点之间的最长距离最短,求该最短的最长距离。

解题思路:用树形dp求出初始每棵树中最长的链,最终答案只有两种情况,两点分别在两棵树上或两点在同一棵树上。如果两点在两棵树上,则将每棵树最长链的长度从大到小排序,计为a1,a2,a3...an,答案为(a1+1)/2+(a2+1)/2+1和a2+a3+2。因为我们把每棵树连到最长链的中点,则除了最长链所在的树,其余的树互相之间相互连通需要加两条边。那么答案就是两点所在树形成的链的一半(向上取整)加上2。而如果两点在同一颗树上,只需要在计算最长链的时候保存最长链即可。最后将两种情况的答案取较大值即可。

代码:

#include<iostream>
#include<string>
#include<string.h>
#include<stdlib.h>
#include<cstdio>
#include<stdio.h>
#include<set>
#include<map>
#include<deque>
#include<stack>
#include<vector>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<sstream>
#include<istream>
#include<ostream>
#include<sstream>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
const int maxn = 100010;
struct edge {
    int to, next;
}e[maxn << 1];
int head[maxn], f[maxn], dp[maxn], tmp, ans, a[maxn];
bool vis[maxn], ok;
int cnt, sz;
int getf(int x) { return f[x] == x ? x : f[x] = getf(f[x]); }
bool cmp(int x, int y) { return x > y; }
void init(int n)
{
    memset(head, -1, sizeof head);
    memset(e, 0, sizeof e);
    memset(vis, 0, sizeof vis);
    memset(dp, 0, sizeof dp);
    ans = 0;
    for (int i = 0; i < n; i++)
    {
        f[i] = i;
    }
}
void add(int x, int y)
{
    e[cnt].to = y;
    e[cnt].next = head[x];
    head[x] = cnt++;
    e[cnt].to = x;
    e[cnt].next = head[y];
    head[y] = cnt++;
}
void dfs(int cur)
{
    vis[cur] = true;
    int lx = 0;//当前节点的子节点的最大深度
    for (int i = head[cur]; ~i; i = e[i].next)
    {
        int v = e[i].to;
        if (vis[v])continue;
        dfs(v);
        dp[cur] = max(dp[cur], dp[v] + 1);
        tmp = max(tmp, lx + dp[v] + 1);//求以cur为根的树的最长链
        lx = max(lx, dp[v] + 1);//更新最大深度
    }
}
int main()
{
    int n, m, x, y;
    scanf("%d%d", &n, &m);
    init(n);
    for (int i = 0; i < m; i++)
    {
        scanf("%d%d", &x, &y);
        add(x, y);
        if (getf(x) > getf(y))swap(x, y);
        f[y] = f[x];
    }
    memset(vis, 0, sizeof vis);
    for (int i = 0; i < n; i++)
    {
        if (vis[i])continue;
        tmp = 0;
        dfs(i);
        a[sz++] = (tmp + 1) / 2;//将最长链的一半存入
        ans = max(tmp, ans);
    }
    a[sz++] = 0;
    sort(a, a + sz, cmp);
    printf("%d\n", max(ans, max(a[1] + a[2] + 2, a[0] + a[1] + 1)));
    return 0;
}

【解题报告】Kattis - adjoin 树形dp相关推荐

  1. [JZOJ 5911] [NOIP2018模拟10.18] Travel 解题报告 (期望+树形DP)

    题目链接: http://172.16.0.132/senior/#contest/show/2530/1 题目: EZ同学家里非常富有,但又极其的谦虚,说话又好听,是个不可多得的人才.       ...

  2. 解题报告 (十四) 数位DP

    文章目录 数位DP 解题报告 HDU 4722 Good Numbers HDU 2089 不要62 HDU 3555 Bomb HDU 3652 B-number PKU 3252 Round Nu ...

  3. [HDU4628]解题报告,状态压缩dp

    每天一篇结题报告计划(2/∞) 今天要讲的是一篇很有意思的状压dp,数学课一直在想这题,然后一节课没听emmm. Pieces You heart broke into pieces.My strin ...

  4. C++解题报告——Rima(字典树+树形DP)

    题目描述 Adrian对单词押韵很感兴趣.如果两个单词的最长公共后缀的长度与两个单词中较长那个的长度一样,或者等于较长单词的长度减一,则这两个单词押韵.换句话说,如果A,B的最长公共后缀LCS(A,B ...

  5. 糖果(2019第十届蓝桥杯省赛C++A组I题) 解题报告(状压dp) Apare_xzc

    糖果(2019第十届蓝桥杯省赛C++A组I题) 解题报告(状压dp) xzc 2019/4/5 试题 I: 糖果 时间限制: 1.0s 内存限制: 256.0MB 本题总分:25分 [问题描述]    ...

  6. 动态规划报告(树形DP+概率DP

    动态规划报告 树形dp 树形 DP,即在树上进行的 DP.由于树固有的递归性质,树形 DP 一般都是递归进行的.一般需要在遍历树的同时维护所需的信息 以一道题目为例 2022CCPC桂林站G Grou ...

  7. 0x54. 动态规划 - 树形DP(习题详解 × 12)

    目录 0x54.1 树形DP Problem A. 没有上司的舞会 Problem B. 战略游戏 0x54.2 树上背包 Problem A. 选课 Problem B.[数据加强版]选课(树上背包 ...

  8. 解题报告(三)多项式求值与插值(拉格朗日插值)(ACM / OI)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量的题解和代码,题目难度不一 ...

  9. 【HDU - 6662】Acesrc and Travel(树形dp,博弈dp)

    题干: Acesrc is a famous tourist at Nanjing University second to none. During this summer holiday, he, ...

  10. 【HDU - 5452】Minimum Cut(树形dp 或 最近公共祖先lca+树上差分,转化tricks,思维)

    题干: Given a simple unweighted graph GG (an undirected graph containing no loops nor multiple edges) ...

最新文章

  1. javascript原理_JavaScript程序包管理器工作原理简介
  2. oracle终止dbms调度,Oracle使用DBMS_JOB创建的数据库作业,遇到数据库关闭状态的调度...
  3. MATLAB 未找到支持的编译器或 SDK。您可以安装免费提供的 MinGW-w64 C/C++ 编译器
  4. 如何进入鸿蒙系统,魅族确认接入鸿蒙系统!并且即将亮相和用户碰面
  5. 把MSSQL2005转换成MSSQL2000
  6. 开发中常用的19 条 MySQL 优化技巧
  7. 动态规划算法的应用模型
  8. 古代的政令 —— 两汉均输
  9. 数学知识与计算机科学中的应用,浅谈计算机科学技术在数学思想中的应用
  10. 【渝粤教育】国家开放大学2018年秋季 0169-22T工程制图基础 参考试题
  11. 计算机专业英语词汇pdf,计算机专业英语词汇(完美排版,大容量打印版).pdf.pdf
  12. 拆解兼容Qi充电标准的三星无线充电器
  13. 网络工程师十个常见面试问题
  14. 怎么解除计算机管理员的身份,怎么取消管理员权限(怎么取消管理员取得所有权)...
  15. 【GA MTSP】基于matlab遗传算法求解多旅行商问题(同始终点)【含Matlab源码 1338期】
  16. .net core发布到IIS上出现 HTTP 错误 500.19,错误代码:0x8007000d
  17. jsp文件打开为记事本怎么办
  18. C语言程序设计--存储单元术语解析
  19. Whitted光线追踪
  20. iOS 上架流程图文详解2022版 (上)

热门文章

  1. UiPath Excel 复制粘贴
  2. 使用计算机键盘的基本步骤,电脑如何用键盘开机_台式电脑键盘开机方法-win7之家...
  3. 服务器网卡支持热插拔吗,HDMI接口能“热插拔”吗?这篇告诉你
  4. iOS清除缓存功能开发
  5. 项目Kick Off的作用
  6. 计算机是1946年由科学家发明,1946年第一台计算机叫什么
  7. Frobenius自同构
  8. 游戏网站运营文章——原神七七介绍
  9. java se runtime environment 6.0_Java SE Runtime Environment v6.0 Update 16
  10. 爆炒猪肚的做法 爆炒猪肚怎样炒才脆