题目链接:http://codeforces.com/contest/456/problem/E

题意:给出N个点,M条边,组成无环图(树),给出Q个操作,操作有两种:

1 x,输出x所在的联通块的最长路;

2 x y,若x和y在同一联通块,则不操作;若不在同一联通块,则选择这两个联通块的各一个城市连一条边,使新的联通块的最长路最短,若有多种选择则随便选。

题解:就是先求出一开始几个连通块的最长路,然后之后q个操作没必要真正意义上连边,只要用并查集更新一下就行了,最后代码有些事要优化的具体看一下代码。

还有求最长路就是求数的直径就行,树的直径就是两遍dfs or bfs。

#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
using namespace std;
const int M = 3e5 + 10;
int f[M] , dis[M] , head[M] , e;
void init(int n) {
for(int i = 1 ; i <= n ; i++) f[i] = i;
memset(dis , 0 , sizeof(dis));
memset(head , -1 , sizeof(head));
e = 0;
}
struct Edge {
int u , v , next;
}edge[M << 1];
void add(int u , int v) {
edge[e].v = v;
edge[e].next = head[u];
head[u] = e++;
}
int find(int x) {
if(x == f[x]) return x;
int tmp = find(f[x]);
return f[x] = tmp;
}
struct TnT {
int pos , step;
TnT(){}
TnT(int pos , int step):pos(pos) , step(step) {}
};
bool vis[M] , vs[M];
int maxi , maxd , father;
void dfs(int u , int pre , int step) {
f[u] = father;
if(step > maxd) {
maxd = step;
maxi = u;
}
for(int i = head[u] ; i != -1 ; i = edge[i].next) {
int v = edge[i].v;
if(v == pre) continue;
dfs(v , u , step + 1);
}
}
int main() {
int n , m , q;
scanf("%d%d%d" , &n , &m , &q);
init(n);
for(int i = 0 ; i < m ; i++) {
int u , v;
scanf("%d%d" , & u , &v);
add(u , v);
add(v , u);
//一开始的时候先不要直接并查集如果一开始就并查集的话后面就一定会用到find函数,这样会超时的。
}
for(int i = 1 ; i <= n ; i++) {
if(f[i] == i) {
father = i;
//在求最长路的同时进行并查集,父节点全都定为i这样就不会超时了。优化就在这里,稍微注意一下就行。
maxd = -1;
dfs(i , -1 , 0);
maxd = -1;
dfs(maxi , -1 , 0);
dis[i] = maxd;
}
}
while(q--) {
int x , y , t;
scanf("%d" , &t);
if(t == 1) {
scanf("%d" , &x);
int gg = find(x);
printf("%d\n" , dis[gg]);
}
else {
scanf("%d%d" , &x , &y);
int a = find(x) , b = find(y);
if(a == b) continue;
else {
f[a] = b;
dis[b] = max(max(dis[a] , dis[b]) , (dis[a] + 1) / 2 + (dis[b] + 1) / 2 + 1);
//两个连通块连在一起怎么使得连在一起后使得这个连通块的最长路尽量的短,那么显然要中点和中点连在一起。
}
}
}
return 0;
}

codeforces 456 E. Civilization(并查集+数的直径)的更多相关文章

  1. 51 nod 1427 文明 (并查集 + 树的直径)

    1427 文明 题目来源: CodeForces 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 160 难度:6级算法题   安德鲁在玩一个叫“文明”的游戏.大妈正在帮助他. 这个游 ...

  2. Codeforces Round #260 (Div. 1) C. Civilization 并查集,直径

    C. Civilization Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/455/probl ...

  3. Codeforces 455C Civilization(并查集+dfs)

    题目链接:Codeforces 455C Civilization 题目大意:给定N.M和Q,N表示有N个城市,M条已经修好的路,修好的路是不能改变的.然后是Q次操作.操作分为两种.一种是查询城市x所 ...

  4. CodeForces 455C Civilization (并查集+树的直径)

    Civilization 题目链接: http://acm.hust.edu.cn/vjudge/contest/121334#problem/B Description Andrew plays a ...

  5. Codeforces 859E Desk Disorder 并查集找环,乘法原理

    题目链接:http://codeforces.com/contest/859/problem/E 题意:有N个人.2N个座位.现在告诉你这N个人它们现在的座位.以及它们想去的座位.每个人可以去它们想去 ...

  6. Codeforces Gym 100463E Spies 并查集

    Spies Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100463/attachments Desc ...

  7. Codeforces - 828C String Reconstruction —— 并查集find()函数

    题目链接:http://codeforces.com/contest/828/problem/C C. String Reconstruction time limit per test 2 seco ...

  8. CodeForces 731C C - Socks 并查集

    Description Arseniy is already grown-up and independent. His mother decided to leave him alone for m ...

  9. CodeForces 722C Destroying Array (并查集)

    题意:给定 n 个数,然后每次破坏一个位置的数,那么剩下的连通块的和最大是多少. 析:用并查集来做,从后往前推,一开始什么也没有,如果破坏一个,那么我们就加上一个,然后判断它左右两侧是不是存在,如果存 ...

随机推荐

  1. codeforces 322 B Ciel and Flowers

    题目链接 有红绿蓝三种颜色的画,每种拿三朵可以组成一束花,或者各拿一朵组成花束,告诉你每种花的数目,求出可能组成最多的花束. 如果你的代码过不了,考虑一下 8 8 9这种组合.  因为数据量很大,我的 ...

  2. 保存MTLAB图片是想去掉白边

    在做一些matlab小实验的时候,生成的图片需要临时保存的时候会有多余的白边,如何能解决这种问题? 输入 iptsetpref('ImshowBorder','tight'); 后,再show一次图即 ...

  3. Python 之父再发文:构建一个 PEG 解析器

    花下猫语: Python 之父在 Medium 上开了博客,现在写了两篇文章,本文是第二篇的译文.前一篇的译文 在此 ,宣布了将要用 PEG 解析器来替换当前的 pgen 解析器. 本文主要介绍了构建 ...

  4. ieda控制台缓冲区限制问题

    一.现象 控制台输出数据若超过默认值时,将从后向前取默认值大小数据(1024) 二.解决方案 1.配置文件(idea安装目录/bin/idea.properties) 2.找到该栏:idea.cycl ...

  5. cdh5-MariaDB 配置(暂未排版)

    在多数分布MariaDB的设施默认设置使用保守的缓冲区的大小和内存使用. 使用保守的缓冲区大小和内存使用率 Cloudera的数据库管理服务器,监控活动,报告管理,Cloudera 导航,Hive 的 ...

  6. 对vue中nextTick()的理解及使用场景说明

    异步更新队列: 首先我们要对vue的数据更新有一定理解: vue是依靠数据驱动视图更新的,该更新的过程是异步的. 即:当侦听到你的数据发生变化时, Vue将开启一个队列(该队列被Vue官方称为异步更新 ...

  7. 鲜为人知的maven标签解说

    目录 localRepository interactiveMode offline pluginGroups proxies servers mirrors profiles 使用场景 出现位置 激 ...

  8. 洛谷 P2044 [NOI2012]随机数生成器

    题意简述 读入X[0], m, a, c, n和g $ X[n+1]=(a*X[n]+c)\mod m $ 求X数列的第n项对g取余的值. 题解思路 矩阵加速 设\[ F=\begin{bmatrix ...

  9. 开发规范 小白进阶 python代码规范化

    开发规范 软件开发,规范项目的目录结构,代码规范,遵循 PeP8规范等等,让你更加清晰的,合理开发 一功能分类(文件名) settings.py配置文件 配置文件放一些静态参数, 划归固定的路径,文件 ...

  10. Kaggle比赛(二)House Prices: Advanced Regression Techniques

    房价预测是我入门Kaggle的第二个比赛,参考学习了他人的一篇优秀教程:https://www.kaggle.com/serigne/stacked-regressions-top-4-on-lead ...