Codeforces Round #260 (Div. 1)??Civilization_html/css_WEB-ITnose

题目链接

题意:
n个点,m条边的森林,q次操作。每次操作:1、询问x所在树的直径 2、合并x和y所在的树,使得合并后的直径最小
(1?≤?n?≤?3·105; 0?≤?m?<?n ; 1?≤?q?≤?3·105)
分析:
没有读到图是森林。。。做的好纠结
最开始将每个树都求一下直径,之后使用并查集处理,每次合并直径:至少是两个树的直径,或者将两个直径的最中间的部分连接求直径

  1. const int MAXN = 310000;int rt[MAXN], ans[MAXN];VI G[MAXN];bool vis[MAXN];void init(int n){ REP(i, n) { vis[i] = false; ans[i] = 0; G[i].clear(); rt[i] = i; }}int find(int n){ return n == rt[n] ? n : rt[n] = find(rt[n]);}void merge(int a, int b){ int fa = find(a), fb = find(b); if (fa != fb) { rt[fa] = fb; ans[fb] = max(ans[fb], (ans[fb] + 1) / 2 + (ans[fa] + 1) / 2 + 1); ans[fb] = max(ans[fa], ans[fb]); }}int Max, id;void dfs(int u, int fa, int dep){ vis[u] = true; REP(i, G[u].size()) { int v = G[u][i]; if (v != fa) dfs(v, u, dep + 1); } if (dep > Max) { Max = dep; id = u; }}int main(){ int n, m, q; while (~RIII(n, m, q)) { init(n + 1); REP(i, m) { int a, b; RII(a, b); G[a].push_back(b); G[b].push_back(a); int fa = find(a), fb = find(b); rt[fa] = fb; } FE(i, 1, n) { if (!vis[i]) { Max = -1; dfs(i, -1, 0); Max = -1; dfs(id, -1, 0); ans[find(i)] = Max; } } REP(i, q) { int op; RI(op); if (op == 2) { int a, b; RII(a, b); merge(a, b); } else { int a; RI(a); WI(ans[find(a)]); } } } return 0;}

登录后复制

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

点点赞赏,手留余香

给TA打赏
共0人
还没有人赞赏,快来当第一个赞赏的人吧!
    编程技术

    IE6不支持:hover伪类效果的解决办法_html/css_WEB-ITnose

    2025-3-28 13:49:29

    编程技术

    CSS和JS去掉链接虚线框的多种方法_html/css_WEB-ITnose

    2025-3-28 13:49:36

    0 条回复 A文章作者 M管理员
    欢迎您,新朋友,感谢参与互动!
      暂无讨论,说说你的看法吧
    个人中心
    购物车
    优惠劵
    今日签到
    私信列表
    搜索