原题:http://codeforces.com/contest/699/problem/D

题目中所描述的从属关系,可以看作是一个一个块,可以用并查集来维护这个森林。这些从属关系中会有两种环,第一种是一个点从自身出发到自己,这说明该点是一棵子树的根;第二种是从一点出发到另外一个点。这两种情况在并查集合并的时候都会失败,因为合并时他们都已经属于一个子树,我们现在需要做的就是将这些子树合并,这时我们要优先对生成第二种环的子树进行合并,因为这些从属关系一定是需要修改的,第一种情况有一个点可以不需要修改,作为最后合并好的树的根节点。最后,总的操作数等于子树的个数减一,因为最后合并的树的根节点不需要修改。

 #include <bits/stdc++.h>
using namespace std;
const int maxn = ;
int a[maxn];
int f[maxn];//维护并查集
int book[maxn];//标记,为1 的点输出改变后的值,为0输出原值
int find(int x){
if(f[x] == x)
return x;
return f[x] = find(f[x]);
}
int merge(int x,int y){
int u = find(x);
int v = find(y);
if(u != v){
f[v] = u;
return ;
}
return ;
}
int main(){
int n;
scanf("%d",&n);
//并查集初始化
for(int i = ;i<=n;i++){
scanf("%d",&a[i]);
f[i] = i;
}
int cnt = ;//操作计数
int pre = -;//记录需要合并的前一个点
for(int i = ;i<=n;i++){
//对第二种情况的点进行合并
if(!merge(a[i],i) && a[i]!=i){
cnt++;
if(pre != -){
merge(i,pre);
}
pre = i;
book[i] = ;
}
}
//对第一种情况进行合并
for(int i = ;i<=n;i++){
if(i == f[i]){
cnt++;
book[i] = ;
if(pre != -){
merge(i,pre);
}
pre = i;
}
}
printf("%d\n",cnt-);
for(int i = ;i<=n;i++){
if(book[i])
printf("%d ",f[i]);
else
printf("%d ",a[i]);
}
return ;
}

Codeforces 699D Fix a Tree 并查集的更多相关文章

  1. Codeforces Round #363 (Div. 2) D. Fix a Tree —— 并查集

    题目链接:http://codeforces.com/contest/699/problem/D D. Fix a Tree time limit per test 2 seconds memory ...

  2. Codeforces Round #363 (Div. 2)D. Fix a Tree(并查集)

    D. Fix a Tree time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  3. 【并查集】【模拟】Codeforces 698B & 699D Fix a Tree

    题目链接: http://codeforces.com/problemset/problem/698/B http://codeforces.com/problemset/problem/699/D ...

  4. CodeForces 698B Fix a Tree (并查集应用)

    当时也是想到了并查集,但是有几个地方没有想清楚,所以就不知道怎么写了,比如说如何确定最优的问题.赛后看了一下别人的思路,才知道自己确实经验不足,思维也没跟上. 其实没有那么复杂,这个题目我们的操作只有 ...

  5. 【CodeForces】915 F. Imbalance Value of a Tree 并查集

    [题目]F. Imbalance Value of a Tree [题意]给定n个点的带点权树,求所有路径极差的和.n,ai<=10^6 [算法]并查集 [题解]先计算最大值的和,按点权从小到大 ...

  6. Codeforces 731C:Socks(并查集)

    http://codeforces.com/problemset/problem/731/C 题意:有n只袜子,m天,k个颜色,每个袜子有一个颜色,再给出m天,每天有两只袜子,每只袜子可能不同颜色,问 ...

  7. Hdu.1325.Is It A Tree?(并查集)

    Is It A Tree? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) To ...

  8. Is It A Tree?(并查集)

    Is It A Tree? Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 26002   Accepted: 8879 De ...

  9. CF109 C. Lucky Tree 并查集

    Petya loves lucky numbers. We all know that lucky numbers are the positive integers whose decimal re ...

随机推荐

  1. 直线的参数方程ABC

    直线的参数方程的来源 如图所示, 直线\(l\)的倾斜角为\(\theta\),经过定点\(P_0(x_0,y_0)\),在直线上有一动点\(P(x,y)\),如果我们取直线的单位方向向量\(\vec ...

  2. XCodeo如何去除多余的模拟器---学习笔记七

    首先退出Xcode并且关闭模拟器: 然后在终端(Terminal)输入如下2行命令: sudo killall -9 com.apple.CoreSimulator.CoreSimulatorServ ...

  3. UINavigationController的创建和相关设置---学习笔记四

    导航控制器 一.设置字体大小,背景等. 二.自定义返回按钮. 三.设置手势. 一.导航中也有个appearance属性,通过它可以设置所有导航的颜色. 二.自定义返回按钮. 1.首先需要知道的是,要把 ...

  4. Java 基础【13】 文件(文件夹) 创建和删除

    使用 java.io.file 创建文件(文件夹),算是 java 最基础的知识,但实战项目中还是需要知晓细节. 比如 File 类中的 mkdir() 和 mkdirs() 的区别. JDK API ...

  5. 《JavaScript高级程序设计》 - 读书笔记 - 第4章 变量、作用域和内存问题

    4.1 基本类型和引用类型的值 JavaScript变量是松散类型的,它只是保存特定值的一个名字而已. ECMAScript变量包含两种数据类型的值:基本类型值和引用类型值.基本类型值指的是简单的数据 ...

  6. 【jQuery api】 $.type(obj)

    用来获取JavaScript数据类型[[Class]]的对象 <!DOCTYPE html> <html> <head> <script src=" ...

  7. POSIX字符集

    [. .] 排序元素 [= =] 等价元素 类别   匹配字符 [:alnum:] 数字字符 [:alpha:]  字母字符 [:blank:]  空格与制表符 [:cntrl:] 控制字符 [:di ...

  8. 线段树 HDU 3397(真)

    5 种操作  0 1 然后 异或 似乎这种2个更新的先后每次都搞不清 覆盖有覆盖就可以不异或 也不知道为什么 #include<stdio.h> #include<string.h& ...

  9. js限制输入框只能输入数字

    分享下js限制输入框中只能输入数字的方法,包括整数与小数,分享几个例子,有需要的朋友参考下. 1.使用正则表达式限制输入框只能输入数字: <input type="text" ...

  10. js判断用户的浏览设备是移动设备还是PC

    <script type="text/javascript"> function browserRedirect() { var sUserAgent = naviga ...