题目链接: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. C# 二维码的生成

    nuget 搜索qrcodenet,然后选择下载gma.qrcodenet public partial class Form1 : Form { public Form1() { Initializ ...

  2. Qtech 暑假未讲到的算法(不完全)

    一.数据结构:    优先队列.堆.RMQ问题(区间最值问题,可以用线段树解决,还有一个Sparse-Table算法).排序二叉树.划分树.归并树.....   字符串处理:    KMP.字典树.后 ...

  3. UE4 打包详细流程

    这两天试着把之前做的一个UE4项目在安卓机上运行下,于是乎有了下面的一个打包血泪史. 首先呢,肯定是下载好了UE的源码了,我用的是4.18. 安装步骤可以先参考下官方的教程http://api.unr ...

  4. Zookeeper 学习笔记(一)之功能介绍

    Zookeeper 主要在以下场景中可以使用 一,命名服务(用到了zookeeper的文件系统) 命名服务是指通过指定的名字来获取资源或者服务的地址,利用zk创建一个全局的路径,提供服务的地址或者一个 ...

  5. javascript+jQuery补充

    一.jQuery事件绑定 <div class='c1'> <div> <div class='title'>菜单一</div> <div cla ...

  6. 01-Spring Security框架学习--入门(二)

    一.入门案例 Spring Security 自定义登录界面 通过之前的一节 01-Spring Security框架学习--入门(一)的简单演示,Spring security 使用框架自带的登录界 ...

  7. PyCharm如何导入python项目

    Pycharm导入python项目 进入PyCharm后,点击File→Open,然后在弹窗中选择需要导入项目的文件夹: 打开了python项目后,需要配置该项目对应的python才可以正常运行: 配 ...

  8. java并发编程(十四)----(JUC原子类)对象的属性修改类型介绍

    今天我们介绍原子类的最后一个类型--对象的属性修改类型: AtomicIntegerFieldUpdater,AtomicLongFieldUpdater,AtomicReferenceFieldUp ...

  9. 通过注解实现通用导出Excel

    Javaweb开发中数据的导入导出很常见,每次我们都需要写很多代码,所以我就在想能不能写一些通用的方法,之前已经在网上 整理过一些通用的方法,最近在网上看到一位牛人封装的更加简介,自己拿过来整理了一下 ...

  10. 解决微信二次分享失败--后面被加上from=singlemessage&isappinstalled=0的解决方案

    首次分享成功,点开后再次分享或第三次分享就失败了 1.检查你分享的链接,看是否多了两个参数,微信分享会根据分享的不同,为原始链接拼接: 朋友圈   from=timeline&isappins ...