CF455C Civilization (并查集)
CF456E
Codeforces Round #260 (Div. 1) C
Codeforces Round #260 (Div. 2) E
http://codeforces.com/contest/455/problem/C
|
C. Civilization
time limit per test
1 second memory limit per test
256 megabytes input
standard input output
standard output Andrew plays a game called "Civilization". Dima helps him. The game has n cities and m bidirectional roads. The cities are numbered from 1 to n. Between any pair of cities there either is a single (unique) path, or there is no path at all. A path is such a sequence of distinct cities v1, v2, ..., vk, that there is a road between any contiguous cities vi and vi + 1 (1 ≤ i < k). The length of the described path equals to (k - 1). We assume that two cities lie in the same region if and only if, there is a path connecting these two cities. During the game events of two types take place:
Dima finds it hard to execute Andrew's queries, so he asks you to help him. Help Dima. Input
The first line contains three integers n, m, q (1 ≤ n ≤ 3·105; 0 ≤ m < n; 1 ≤ q ≤ 3·105) — the number of cities, the number of the roads we already have and the number of queries, correspondingly. Each of the following m lines contains two integers, ai and bi (ai ≠ bi; 1 ≤ ai, bi ≤ n). These numbers represent the road between cities ai and bi. There can be at most one road between two cities. Each of the following q lines contains one of the two events in the following format:
Output
For each event of the first type print the answer on a separate line. Sample test(s)
Input
6 0 6 Output
4 |
题意:
给出N个点,M条边,组成无环图(树),给出Q个操作,操作有两种:
1 x ,输出x所在的联通块的最长路;
2 x y ,若x和y在同一联通块,则不操作;若不在同一联通块,则选择这两个联通块的各一个城市连一条边,使新的联通块的最长路最短,若有多种选择则随便选。
题解:
并查集+树的直径
我是看http://blog.csdn.net/keshuai19940722/article/details/38455333的碉炸题解学会的,简直碉炸。
这题认真看其实不难,只是我当时太怂了没看……
首先我们根据初始的边用求树的直径的方法求出每块的最长路,方法就是两遍dfs,第一遍找距离起点最远的点x,这个x肯定是最长路的一端,然后我们从x再dfs一遍,得到最长路md[x],顺便把整个块的father设为x。
然后操作一就很容易实现,主要是操作二。操作二其实不用真的去连那条边,只要心中有那条边就行,因为连起来后其实主要我们也只看每个块最长路md[x],其他信息都不用管。设两个块的祖先为fx,fy,设fx的最长路不小于fy的最长路,则我们要把fy的father设为fx,然后更新md[fx]。这个厉害了,我们只要一个超碉的式子就能得到新的md[fx]:
md[fx]=max(md[fx], (md[fx]+)/ + (md[fy]+)/ + );
就是把[x块的最长路的中间点]连接[y块的最长路的中间点],得到的新路的长度是(x块最长路的一半)加上(y块最长路的一半)加上1。
怪不得天梯第一的tourist大神能十多分钟做出来,果然水,不要不服!只是我们比题还水,一下看不出来这样做…
代码:
//#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<stack>
#include<queue>
using namespace std;
#define ll long long
#define usint unsigned int
#define mz(array) memset(array, 0, sizeof(array))
#define minf(array) memset(array, 0x3f, sizeof(array))
#define REP(i,n) for(i=0;i<(n);i++)
#define FOR(i,x,n) for(i=(x);i<=(n);i++)
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define WN(x) printf("%d\n",x);
#define RE freopen("D.in","r",stdin)
#define WE freopen("1biao.out","w",stdout) const int maxn=; struct EDGE{
int v,next;
}e[maxn<<];
int head[maxn],en;
int f[maxn],md[maxn];
int n,m,q;
int maxd,maxi,thefather;
void add(int x,int y){
e[en].v=y;
e[en].next=head[x];
head[x]=en++;
} int getfather(int x){
return f[x]==x ? x:f[x]=getfather(f[x]);
} void link(int x,int y){
int fx,fy;
fx=getfather(x);
fy=getfather(y);
if(fx==fy)return;
if(md[fx]<md[fy])swap(fx,fy);
md[fx]=max(md[fx], (md[fx]+)/ + (md[fy]+)/ + );
f[fy]=fx;
} void dfs(int x,int prex,int step){
f[x]=thefather;
if(step>maxd){
maxd=step;
maxi=x;
}
for(int i=head[x]; i!=-; i=e[i].next)
if(e[i].v!=prex) dfs(e[i].v,x,step+);
} void check(int a[],int n){
for(int i=;i<n;i++)
printf("%d ",a[i]);
puts("");
} int main()
{
int i,x,y,z;
while(scanf("%d%d%d",&n,&m,&q)!=EOF){
memset(head,-,sizeof(head));
en=;
REP(i,m) {
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
for(i=; i<=n ;i++)
f[i]=i;
for(i=; i<=n; i++)
if(f[i]==i){
maxd=-;
thefather=i;
dfs(i,-,);
maxd=-;
thefather=maxi;
dfs(thefather,-,);
md[thefather]=maxd;
}
REP(i,q){
scanf("%d",&z);
if(z==){
scanf("%d",&x);
printf("%d\n",md[getfather(x)]);
}else{
scanf("%d%d",&x,&y);
link(x,y);
// check(md,n+1);
// check(f,n+1);
}
}
}
return ;
}
CF455C Civilization (并查集)的更多相关文章
- cf455C Civilization (并查集)
并查集维护每个联通块的直径和最小的最大深度,每次连得时候连的肯定是最大深度最小的那两个点 #pragma GCC optimize(3) #include<bits/stdc++.h> # ...
- Codeforces Round #260 (Div. 1) C. Civilization 并查集,直径
C. Civilization Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/455/probl ...
- Codeforces 455C Civilization(并查集+dfs)
题目链接:Codeforces 455C Civilization 题目大意:给定N.M和Q,N表示有N个城市,M条已经修好的路,修好的路是不能改变的.然后是Q次操作.操作分为两种.一种是查询城市x所 ...
- CodeForces 455C Civilization (并查集+树的直径)
Civilization 题目链接: http://acm.hust.edu.cn/vjudge/contest/121334#problem/B Description Andrew plays a ...
- CodeForces - 455C Civilization (dfs+并查集)
http://codeforces.com/problemset/problem/455/C 题意 n个结点的森林,初始有m条边,现在有两种操作,1.查询x所在联通块的最长路径并输出:2.将结点x和y ...
- CodeForces 455C Civilization(并查集+树直径)
好久没有写过图论的东西了,居然双向边要开两倍空间都忘了,不过数组越界cf居然给我报MLE??这个题题意特别纠结,一开始一直不懂添加的边长是多长... 题意:给你一些点,然后给一些边,注意没有重边 环, ...
- codeforces 456 E. Civilization(并查集+数的直径)
题目链接:http://codeforces.com/contest/456/problem/E 题意:给出N个点,M条边,组成无环图(树),给出Q个操作,操作有两种: 1 x,输出x所在的联通块的最 ...
- BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]
4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...
- 关押罪犯 and 食物链(并查集)
题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值"( ...
随机推荐
- Leetcode H-index
Given an array of citations (each citation is a non-negative integer) of a researcher, write a funct ...
- 【BZOJ-3712】Fiolki LCA + 倍增 (idea题)
3712: [PA2014]Fiolki Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 303 Solved: 67[Submit][Status] ...
- java integer对象判断两个数字是否相等
java integer对象判断两个数字是否相等,不一定对 问题发生的背景:javaweb的项目,起先,因为在java中实体类中的int类型在对象初始化之后会给int类型的数据默认赋值为0,这样在很多 ...
- Uva1515 Pool construction
Time Limit: 3000MS64bit IO Format: %lld & %llu 网络流 最小割 心生绝望,用了好久的网络流模板居然是错的. ↑居然之前还侥幸能过一堆(并不)题. ...
- win7、win8上SaveFileDialog窗口跳不出的问题
xp上做的开一个线程 线程中数据以Excel形式保存到指定文件中的程序 放到win7 win8上都不跳出保存的对话框? 解决: 在win7.win8上都要对线程 在线程启动前设置其单元状态.设置为 ...
- 数据结构算法C语言实现(三十二)--- 9.1静态查找表
一.简述 静态查找表又分为顺序表.有序表.静态树表和索引表.以下只是算法的简单实现及测试,不涉及性能分析. 二.头文件 /** author:zhaoyu date:2016-7-12 */ #inc ...
- centos7安装eclipse
centos7安装eclipse Eclipse是一个集成开发环境(IDE),包含一个基工作区和定制环境的可扩展插件系统.大部分使用 Java 编写,Eclipse 可以用来开发应用程序.通过各种插件 ...
- UML用例图
- Linux进程关闭和后台运行解析
1.问题背景 Java是跨平台的,大部分程序也都是在Linux服务器上运行的.但是很多朋友其实对服务器了解并不多,对相关知识也是一知半解.很多概念可能知道,但是并不十分清楚,仅仅是基本运用.可能很多新 ...
- jquery selector 基础
转自:http://www.cnblogs.com/zwl12549/archive/2008/08/09/1264163.html query的这套选择符是比较帅气的,借用了XPath2.0和CSS ...