题目链接:http://codeforces.com/contest/699/problem/D

D. Fix a Tree
time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

A tree is an undirected connected graph without cycles.

Let's consider a rooted undirected tree with n vertices, numbered 1 through n.
There are many ways to represent such a tree. One way is to create an array with n integers p1, p2, ..., pn,
where pi denotes
a parent of vertex i (here, for convenience a root is considered its own parent).

For
this rooted tree the array p is [2, 3, 3, 2].

Given a sequence p1, p2, ..., pn,
one is able to restore a tree:

  1. There must be exactly one index r that pr = r.
    A vertex r is a root of the tree.
  2. For all other n - 1 vertices i,
    there is an edge between vertex i and vertex pi.

A sequence p1, p2, ..., pn is
called valid if the described procedure generates some (any) rooted tree. For example, for n = 3 sequences (1,2,2), (2,3,1) and (2,1,3) are
not valid.

You are given a sequence a1, a2, ..., an,
not necessarily valid. Your task is to change the minimum number of elements, in order to get a valid sequence. Print the minimum number of changes and an example of a valid sequence after that number of changes. If there are many valid sequences achievable
in the minimum number of changes, print any of them.

Input

The first line of the input contains an integer n (2 ≤ n ≤ 200 000) —
the number of vertices in the tree.

The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ n).

Output

In the first line print the minimum number of elements to change, in order to get a valid sequence.

In the second line, print any valid sequence possible to get from (a1, a2, ..., an) in
the minimum number of changes. If there are many such sequences, any of them will be accepted.

Examples
input
4
2 3 3 4
output
1
2 3 4 4
input
5
3 2 2 5 3
output
0
3 2 2 5 3
input
8
2 3 5 4 1 6 6 7
output
2
2 3 7 8 1 6 6 7

题意:

有n个节点,给出每个点的父节点。问至少修改多少个节点的父节点,使得这些节点刚好构成一棵树?

题解:

1.经过分析,假设在初始状态有k个集合,那么对于每一个集合,它要么是一棵根节点的父节点为自己的树,要么是一棵根节点的父节点为其子孙的树(虽然不是树,但姑且这么叫,便于理解)。

2.首先用并查集使得每个集合“现出原形”,得到集合后,需要选一个根节点,作为最终树的根节点,父节点为自己的根节点优先被选择,然后再把其他根节点的 父节点改为最终树的根节点。如果选另一种,就需要把它的父节点改为自己,真正作为根节点(这个集合就真真正正是一棵树了)后,再把其他根节点的父节点改为最终树的根节点,这样就多了一次修改。

代码如下:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
#include <algorithm>
using namespace std;
#define ms(a, b) memset((a), (b), sizeof(a))
typedef long long LL;
const double eps = 1e-;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+;
const int maxn = +; int fa[maxn], a[maxn], b[maxn];
int n; int find(int x) { return fa[x]==x? fa[x]=x:find(fa[x]); } void init()
{
scanf("%d",&n);
for(int i = ; i<=n; i++)
scanf("%d",&a[i]), b[i] = a[i], fa[i] = i;
} void solve()
{
for(int i = ; i<=n; i++)
{
int u = a[i], v = i;
int m1 = find(u);
int m2 = find(v); if(m1!=m2)
fa[m2] = m1;
} int rt = ;
for(int i = ; i<=n; i++)
if(fa[i]==i && a[i]==i)
{
rt = i;
break;
} for(int i = ; i<=n; i++)
{
if(fa[i]==i)
{
if(!rt)
rt = i, a[i] = i;
else
a[i] = rt;
}
} int ans = ;
for(int i = ; i<=n; i++)
if(a[i]!=b[i])
ans++; printf("%d\n",ans);
for(int i = ; i<=n; i++)
printf("%d ",a[i]);
} int main()
{
// int T;
// scanf("%d",&T);
// while(T--)
{
init();
solve();
}
return ;
}

Codeforces Round #363 (Div. 2) D. Fix a Tree —— 并查集的更多相关文章

  1. 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 ...

  2. Codeforces Round #363 (Div. 2) 698B Fix a Tree

    D. Fix a Tree time limit per test 2 seconds memory limit per test 256 megabytes     A tree is an und ...

  3. Codeforces Round #363 (Div. 1) B. Fix a Tree 树的拆环

    题目链接:http://codeforces.com/problemset/problem/698/B题意:告诉你n个节点当前的父节点,修改最少的点的父节点使之变成一棵有根树.思路:拆环.题解:htt ...

  4. Codeforces Round #181 (Div. 2) B. Coach 带权并查集

    B. Coach 题目连接: http://www.codeforces.com/contest/300/problem/A Description A programming coach has n ...

  5. Codeforces Round #345 (Div. 1) C. Table Compression dp+并查集

    题目链接: http://codeforces.com/problemset/problem/650/C C. Table Compression time limit per test4 secon ...

  6. Codeforces Round #346 (Div. 2) F. Polycarp and Hay 并查集 bfs

    F. Polycarp and Hay 题目连接: http://www.codeforces.com/contest/659/problem/F Description The farmer Pol ...

  7. Codeforces Round #375 (Div. 2) D. Lakes in Berland 并查集

    http://codeforces.com/contest/723/problem/D 这题是只能把小河填了,题目那里有写,其实如果读懂题这题是挺简单的,预处理出每一块的大小,排好序,从小到大填就行了 ...

  8. Codeforces Round #603 (Div. 2) D. Secret Passwords(并查集)

    链接: https://codeforces.com/contest/1263/problem/D 题意: One unknown hacker wants to get the admin's pa ...

  9. Codeforces Round #360 (Div. 1) D. Dividing Kingdom II 并查集求奇偶元环

    D. Dividing Kingdom II   Long time ago, there was a great kingdom and it was being ruled by The Grea ...

随机推荐

  1. 洛谷——P2878 [USACO07JAN]保护花朵Protecting the Flowers

    P2878 [USACO07JAN]保护花朵Protecting the Flowers 题目描述 Farmer John went to cut some wood and left N (2 ≤ ...

  2. ELK之收集haproxy日志

    由于HAProxy的运行信息不写入日志文件,但它依赖于标准的系统日志协议将日志发送到远程服务器(通常位于同一系统上),所以需要借助rsyslog来收集haproxy的日志.haproxy代理nginx ...

  3. Java创建和解析Json数据方法(三)——json-lib包的使用

    (三)json-lib包的使用         这篇笔记主要介绍json-lib包的创建和解析json数据的方式,主要是的JSONObject.JSONArray和Java对象:beans, maps ...

  4. 【spring boot】在Spring mvc中controller中可以拿到对象信息,但是返回给前台却是什么也没有,解决方案

    如图所示: 最后: 问题解决: 这个原因是因为,User类并未给字段提供get/set方法,所以给前台传递过去的值是空的. 解决方案: 为User类添lombok的注解@Data,为实体类提供get/ ...

  5. 谈oracle数据比对(DBMS_COMPARISON)

    今天是2014-08-19,我今天收到csdn给我发的申请博客专家的邀请,自己感觉实在羞愧啊. 自从换了工作也一直没有精力在写点东西了.今天我一个同事,在群里贴出了一个数据比对的包(DBMS_COMP ...

  6. python 读取共享内存

    测试环境 centos7 python3.6.5 首先使用c创建内存,这里的方法是:作为参数读一个二进制数据文件进去,把文件的内容作为共享内存的内容 定义块 #include <stdio.h& ...

  7. hdu1827之强联通

    Summer Holiday Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  8. log4j:WARN Please initialize the log4j system properly解决的方法

    要解决问题很easy,建立LOG4J 的配置文件就可以. 在src 文件夹下创建配置文件,选 一.择菜单File > New > File,文件名称输入log4j.properties,文 ...

  9. LeetCode85 Maximal Rectangle java题解

    public static int maximalRectangle(char[][] matrix) { int rowNum=matrix.length; if(rowNum==0) return ...

  10. python(17)- 迭代器和生成器及应用

    什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退) 2.可迭代对象 ...