CF698B Fix a Tree 题解 贪心

Fix a Tree

传送门

A tree is an undirected connected graph without cycles.

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

For this rooted tree the array p p p is [ 2 , 3 , 3 , 2 ] [2,3,3,2] [2,3,3,2] .Given a sequence p 1 , p 2 , . . . , p n p_{1},p_{2},...,p_{n} p1,p2,...,pn , one is able to restore a tree:

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

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

You are given a sequence a 1 , a 2 , . . . , a n a_{1},a_{2},...,a_{n} 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 n n ( 2 < = n < = 200000 2<=n<=200000 2<=n<=200000 ) — the number of vertices in the tree.

The second line contains n n n integers a 1 , a 2 , . . . , a n a_{1},a_{2},...,a_{n} a1,a2,...,an ( 1 < = a i < = n 1<=a_{i}<=n 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 ( a 1 , a 2 , . . . , a n ) (a_{1},a_{2},...,a_{n}) (a1,a2,...,an) in the minimum number of changes. If there are many such sequences, any of them will be accepted.

Examples

input #1

4
2 3 3 4

output #1

1
2 3 4 4

input #2

5
3 2 2 5 3

output #2

0
3 2 2 5 3

input #3

8
2 3 5 4 1 6 6 7

output #3

2
2 3 7 8 1 6 6 7

Note

In the first sample, it’s enough to change one element. In the provided output, a sequence represents a tree rooted in a vertex 4 4 4 (because p 4 = 4 p_{4}=4 p4=4 ), which you can see on the left drawing below. One of other correct solutions would be a sequence 2 3 3 2, representing a tree rooted in vertex 3 3 3 (right drawing below). On both drawings, roots are painted red.


In the second sample, the given sequence is already valid.

题面翻译

对于下图中的树,

图1

可以用数组表示为 [ 2 , 3 , 3 , 2 ] [2,3,3,2] [2,3,3,2]。这种可以表示树的数组(即有效)需要符合以下条件:

  1. 有且只有一个索引 r r r ,符合 p r = r p_r=r pr=r 。其中顶点 r r r 是树的根。
  2. 对于所有剩下的 n − 1 n-1 n1 个顶点 i i i 一定要有在 i i i p i p_i pi 之间的边。

比如 数列 ( 1 , 2 , 2 ) (1,2,2) (1,2,2) ( 2 , 3 , 1 ) (2,3,1) (2,3,1) ( 2 , 1 , 3 ) (2,1,3) (2,1,3) 都是因为的数目而导致不有效

现在给你一个数组 a 1 , a 2 , ⋯ , a n a_1,a_2,\cdots ,a_n a1,a2,,an不一定有效的。你需要对数组里面的值,通过最小次数更改,使得这个数组有效

并输出最小更改次数和一个通过最小更改次数而更改成功的有效数组

如果有多种解,只需说出任何一组。

输入格式

第一行是一个整数 n ( 2 ≤ n ≤ 200000 ) n\ (2\le n \le 200000) n (2n200000) ----树的顶点个数。

第二行包含 n n n 个整数 a 1 , a 2 , ⋯ , a n ( 1 ≤ a i ≤ n a_1,a_2,\cdots ,a_n\ (1\le a_i\le n a1,a2,,an (1ain

输出格式

第一行一个整数,最小更改次数

第二行输出任意一个通过最小更改次数而更改成功的有效数组。

说明

  • 第一个样例只需要改一个就好啦!第一个样例输出是一个扎根于顶点 4 4 4 的树(因为 p 4 = 4 p_4=4 p4=4),你可以在下面的图中看到。另一个正确的答案应该是数列 2 , 3 , 3 , 2 2,3,3,2 2,3,3,2,扎根在顶点 3 3 3,也可以在下面的图中看到。两个图中顶点将用红色标出。

图2

  • 第二个样例中,给出的数列已经是有效的了。

注明

以上来自 C o d e F o r c e s ,翻译来源:洛谷。 以上来自 CodeForces,翻译来源:洛谷。 以上来自CodeForces,翻译来源:洛谷。

BestMonkey:CodeForces 你什么时候能完善一下你的 Markdown 格式啊!你知道我复制下来题面还要一个一个删多余的空格吗!你看看人家洛谷啊!(愤怒)
CodeForces:我这是为了提高你们的编辑文本效率啊。(叉腰)
BestMonkey:(直接一拳)

解题思路

先考虑确定根节点:

  • 显然,最后只有根节点是自环。所以,若输入中有自环,那就选它为树的总根。显然,答案不会更劣;
  • 如果一开始没有自环,那选择环上一点作为根即可。

然后处理环。用一个数组存下环上节点的颜色。对于每一个节点染色后 DFS(染的颜色要与之前不同),若找到一个节点颜色与当前节点相同,则说明找到了一个环。此时,只要把当前的点指向总根即可。若没有总根,则设置当前节点为总根,再将当前节点的父亲设为自己。

AC Code

#include<bits/stdc++.h>
using namespace std;
char buf[1048576], *p1, *p2;
template<typename T>inline void Super_Quick_Read(T &x) {bool f = 1;x = 0;char ch = (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 20, stdin), p1 == p2) ? 0 : *p1++);while (ch < '0' || ch > '9') {if (ch == '-') f = !f;ch = (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 20, stdin), p1 == p2) ? 0 : *p1++);}while (ch >= '0' && ch <= '9')x = (x << 1) + (x << 3) + (ch ^ 48), ch = (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 20, stdin), p1 == p2) ? 0 : *p1++);x = (f ? x : -x);return;
}
template<typename T>inline void Quick_Write(T x) {if (x < 0) putchar('-'), x = -x;if (x > 9) Quick_Write(x / 10);putchar(x % 10 + '0');return;
}
int n, a[200005];
int Fa[200005], Color[200005], Root, Tag;
inline void DFS(int u) {if (Color[u]) return;Color[u] = Tag;if (Fa[u] == u) {if (!Root) Root = u;else Fa[u] = Root;return;}if (Color[Fa[u]]) {if (Color[Fa[u]] == Tag) if (!Root) Fa[u] = u, Root = Fa[u];else Fa[u] = Root;return;}DFS(Fa[u]);
}
signed main() {Super_Quick_Read(n);for (register int i = 1; i <= n; ++i) Super_Quick_Read(a[i]);memcpy(Fa, a, sizeof(a));for (register int i = 1; i <= n; ++i) if (Fa[i] == i) {Root = i;break;}for (register int i = 1; i <= n; ++i) ++Tag, DFS(i);int count_change = 0;for (register int i = 1; i <= n; ++i) if (Fa[i] != a[i]) ++count_change;Quick_Write(count_change);puts("");for (register int i = 1; i <= n; i++) Quick_Write(Fa[i]), puts(" ");puts("");return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/810578.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于GitHub的开源讨论系统,赋予网站交互可能

Giscus&#xff1a;让每一条见解直达GitHub&#xff0c;用Giscus开启网站与社区的无缝对话新纪元&#xff01;- 精选真开源&#xff0c;释放新价值。 概览 纯静态网站或博客&#xff0c;由于没有数据存储功能&#xff0c;经常借助第三方的评论系统以插件的方式集成进来&#x…

uniapp 编译后分包下静态图片404问题解决方案

如上图官方说明&#xff1a; 在分包下建立一个static文件夹即可&#xff1a; 分包内代码引用图片 <image src"/分包名称/img/图片名称"></image> <image src"/dataView/img/图片名称"></image>

SQL执行流程图文分析:从连接到执行的全貌

SQL执行总流程 下面就是 MySQL 执行一条 SQL 查询语句的流程&#xff0c;也从图中可以看到 MySQL 内部架构里的各个功能模块。 MySQL 的架构共分为两层&#xff1a;Server 层和存储引擎层&#xff0c; Server 层负责建立连接、分析和执行 SQL。MySQL 大多数的核心功能模块都在…

Navicat连接SQL server出现:[IM002] [Microsoft][ODBC 驱动程序管理器] 未发现数据源名称并且未指定默认驱动程序(0)

问题 解决方法 一 找到Navicat的安装路径&#xff0c;然后找到sqlncli_x64.msi文件并安装&#xff0c;安装成功后重启Navicat重新进行连接&#xff0c;看是否成功。 解决方法 二 如果方法一没有找到找到sqlncli_x64.msi 还是Navicat的安装路径&#xff0c;然后找到msodbcsql_64…

03-JAVA设计模式-适配器模式

适配器模式 设么是适配器模式 它属于结构型模式&#xff0c;主要用于将一个类的接口转换成客户端所期望的另一种接口&#xff0c;从而使得原本由于接口不兼容而无法协同工作的类能够一起工作。 适配器模式主要解决的是不兼容接口的问题。在软件开发中&#xff0c;经常会有这…

第三十八节 Java 多线程编程

Java 给多线程编程提供了内置的支持。一个多线程程序包含两个或多个能并发运行的部分。程序的每一部分都称作一个线程&#xff0c;并且每个线程定义了一个独立的执行路径。 多线程是多任务的一种特别的形式。多线程比多任务需要更小的开销。 这里定义和线程相关的另一个术语&…

【错误分享】打开Qt编译生成的软件,“无法找到入口”

错误简介 这张图片显示的是一个计算机错误提示窗口&#xff0c;标题为“无法找到入口”。正文内容是&#xff1a;“无法定位程序输入点_Z21qRegisterResourceDataaiPKhS0_S0_于动态链接库Qt5Core.dll上。” 这意味着在尝试运行程序时遇到了问题。 具体来说&#xff0c;该错误表…

Vue内置组件Transition用法介绍

Vue 提供了两个内置组件&#xff0c;可以帮助你制作基于状态变化的过渡和动画&#xff1a; <Transition> 会在一个元素或组件进入和离开 DOM 时应用动画。本章节会介绍如何使用它。 <TransitionGroup> 会在一个 v-for 列表中的元素或组件被插入&#xff0c;移动&a…

从大量数据到大数据,King’s SDMS仪器数据采集及科学数据管理系统的应用

对于实验室或检测机构&#xff0c;仪器设备是所有业务开展的基础&#xff0c;数据则是核心命脉&#xff0c;而传统的仪器设备原始数据收集方式&#xff0c;效率低耗时长、操作流程不规范、不易保存与查找、错误率高、易篡改等成了制约检测机构持续高速发展的瓶颈和弊端&#xf…

单例19c RMAN数据迁移方案

一、环境说明 源库 目标库 IP 192.168.37.200 192.168.37.202 系统版本 RedHat 7.9 RedHat 7.9 数据库版本 19.3.0.0.0 19.3.0.0.0 SID beg beg hostname beg rman 数据量 1353M 说明:源库已经创建数据库实例&#xff0c;并且存在用户kk和他创建的表空间…

新规来了!智能音视频技术重塑信贷体验

近日&#xff0c;国家金融监督管理总局发布《固定资产贷款管理办法》《流动资金贷款管理办法》《个人贷款管理办法》&#xff08;以下简称“三个办法”&#xff09;。 具体来看&#xff0c;新规明确了以下要求&#xff1a; 1、明确视频面签、电子签约要求 允许商业银行通过视…

Oracle 19c RAC集群相关日志

1.DB日志&#xff08;数据库日志&#xff09; Redo Log&#xff08;重做日志&#xff09;&#xff1a; 在Oracle数据库中&#xff0c;重做日志记录了数据库发生的所有修改操作&#xff0c;包括数据的插入&#xff0c;更新和删除。在RAC的环境中&#xff0c;每个实例都有自己的重…

Ubuntu22.04搭建CLion C++开发环境

Ubuntu22.04搭建CLion C开发环境 文章目录 Ubuntu22.04搭建CLion C开发环境1.首先下载CLion2.配置c环境3.创建快捷方式Reference 1.首先下载CLion 进入官网https://www.jetbrains.com/clion/download/#sectionlinux 然后进入自己存放这个压缩包的路径中&#xff0c; sudo mkd…

SQLite从出生到现在(发布历史记录)(二十二)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;从 SQLite 3.5.9 迁移到 3.6.0&#xff08;二十一&#xff09; 下一篇&#xff1a;SQLite—系列文章目录 引言&#xff1a; SQLite拥有别人无法比拟的装机量&#xff0c;究竟什么成就了SQLite呢&#xff0c;本…

最长公共子序列、最长上升子序列(LCS与LIS)算法

最长公共子序列、最长上升子序列(LCS与LIS) 最长公共子序列(LCS) #include <bits/stdc.h> using namespace std; #define int long long const int N 1e39; int a[N],b[N],dp[N][N]; signed main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int n,m;cin>>…

大文件传输之为啥传输过程中出现宽带不足的情况

在当今数字化时代&#xff0c;大文件传输已成为企业日常运营的关键环节。然而&#xff0c;许多企业在传输大文件时经常面临宽带不足的问题&#xff0c;这不仅影响了工作效率&#xff0c;还可能导致业务机会的丧失。本文将探讨大文件传输过程中宽带不足的原因&#xff0c;以及镭…

【数据结构】稀疏矩阵的快速转置

【数据结构】稀疏矩阵的转置&#xff08;普通转置 和 快速转置&#xff09; 目录 【数据结构】稀疏矩阵的转置&#xff08;普通转置 和 快速转置&#xff09;三元表稀疏矩阵的转置方法一&#xff08;普通转置&#xff09;复杂度为O(T.muT.nu)方法二&#xff1a;快速转置 复杂度…

聚道云软件连接器助力企业实现CRM与税票系统对接,提升财务管理效率

一、客户介绍&#xff1a;行业翘楚&#xff0c;寻求数字化升级 某企业作为行业内的佼佼者&#xff0c;始终站在市场前沿&#xff0c;不断探索数字化转型的新路径。近年来&#xff0c;随着业务规模的扩大&#xff0c;该企业对于客户关系管理&#xff08;CRM&#xff09;与税务电…

数据分析python代码——数据填充

在Python中&#xff0c;我们通常使用pandas库来处理和分析数据。数据填充是数据预处理的一个重要步骤&#xff0c;用于处理数据中的缺失值。以下是使用pandas库进行数据填充的示例代码&#xff1a; 在数据分析中&#xff0c;处理缺失值&#xff08;空值&#xff09;是一个重要…

AI预测体彩排3第1弹【2024年4月12日预测--第1套算法开始计算第1次测试】

前面经过多个模型几十次对福彩3D的预测&#xff0c;积累了一定的经验&#xff0c;摸索了一些稳定的规律&#xff0c;有很多彩友让我也出一下排列3的预测结果&#xff0c;我认为目前时机已成熟&#xff0c;且由于福彩3D和体彩排列3的玩法完全一样&#xff0c;我认为3D的规律和模…