CodeForces 698B Fix a Tree (并查集应用)
当时也是想到了并查集,但是有几个地方没有想清楚,所以就不知道怎么写了,比如说如何确定最优的问题。赛后看了一下别人的思路,才知道自己确实经验不足,思维也没跟上。
其实没有那么复杂,这个题目我们的操作只有三个 1、确定根节点。2、解环。 3连接子树。
如果题目中给出了一个或者多个根节点,我们任选一个即可,证明:假设有k个可行根节点,那么选择一个不动,改动k-1次,每种选择都是这样。但如果题目中没有可选根节点,就不可以随便去选了,首先明确这种情况一定存在了1个或者多个环,我们一定要从环中选取根节点,因为这样只进行了一次操作就破环了环结构而且确定了根节点,如果在环外选择根节点,则改动为根节点需要1步,解环也需要一步,不是最优解!
为了操作方便,使用并查集寻找环,并将找到第一个环的任意一个节点作为根节点。
在确定了根节点之后,如果遇到其他可行根节点,直接连接到已确定根节点即可,就是连接子树的操作。
注意:这个注意是对我自己说的,我犯了一个低级错误,我在判断环的时候居然没有用find判断,而是用fa判断,当时还感觉很困惑,以为合并方式不对,发现了以后才感觉自己真是好久没做过并查集了。。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 200020
int a[N],fa[N];
int Find(int x)
{
return x==fa[x] ? x : fa[x] = Find(fa[x]);
}
void unin(int x,int y)
{
int fax = Find(x);
int fay = Find(y);
fa[fay] = fax;
}
int main()
{
int root = -,ans=,n;
cin>>n;
for(int i = ; i <= n; i++)
{
cin>>a[i];
fa[i] = i;
if(a[i]==i) root = i;
}
for(int i = ; i <= n; i++)
{
if(i == a[i] && a[i] == root) continue;
else if(a[i] == i && i != root)
{
a[i] = root;
ans++;
unin(root,i);
}
else if(a[i] != i && Find(a[i]) != Find(i))
{
unin(a[i],i);
}
else if(a[i] != i && Find(a[i]) == Find(i))
{
ans++;
if(root == -)
{
root = i;
}
a[i] = root;
unin(root,i);
}
}
cout<<ans<<endl;
for(int i = ; i <= n; i++)
{
if(i==n) cout<<a[i]<<endl;
else cout<<a[i]<<" ";
}
return ;
}
CodeForces 698B Fix a Tree (并查集应用)的更多相关文章
- Codeforces 699D Fix a Tree 并查集
原题:http://codeforces.com/contest/699/problem/D 题目中所描述的从属关系,可以看作是一个一个块,可以用并查集来维护这个森林.这些从属关系中会有两种环,第一种 ...
- 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 ...
- 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 ...
- CodeForces 698B Fix a Tree
并查集,构造. 先看一下图的特殊性,按照这种输入方式,一个点的入度最多只有$1$,因此,问题不会特别复杂,画画图就能知道了. 如果给出的序列中已经存在$a[i]=i$,那么随便取一个$a[i]=i$的 ...
- 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 ...
- 【CodeForces】915 F. Imbalance Value of a Tree 并查集
[题目]F. Imbalance Value of a Tree [题意]给定n个点的带点权树,求所有路径极差的和.n,ai<=10^6 [算法]并查集 [题解]先计算最大值的和,按点权从小到大 ...
- Codeforces 731C:Socks(并查集)
http://codeforces.com/problemset/problem/731/C 题意:有n只袜子,m天,k个颜色,每个袜子有一个颜色,再给出m天,每天有两只袜子,每只袜子可能不同颜色,问 ...
- 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 ...
- Is It A Tree?(并查集)
Is It A Tree? Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 26002 Accepted: 8879 De ...
随机推荐
- Openjudge-NOI题库-对齐输出
题目描述 Description 读入三个整数,按每个整数占8个字符的宽度,右对齐输出它们. 输入输出格式 Input/output 输入格式: 只有一行,包含三个整数,整数之间以一个空格分开. ...
- C#与C++中struct和class的小结
在C#中,struct其实也是可以像class一样封装方法和数据的.请参考如下代码. using System; namespace testDiffInStructClass { public st ...
- 输入身份证号码自动读取生日与性别(delphi)
一.格式介绍: [15位号码格式] 1.第l一6位数为行政区划代码; 2.第7-12位数为出生日期代码; 3.第13---15位数为分配顺序代码; (1).行政区划代码,是指公民第一次申领居民身份证时 ...
- linux系统被入侵后处理经历【转】
背景 操作系统:Ubuntu12.04_x64 运行业务:公司业务系统,爬虫程序,数据队列. 服务器托管在外地机房. 突然,频繁收到一组服务器ping监控不可达邮件,赶紧登陆zabbix监控系统查看流 ...
- Sql Server 表创建以及Ef浅谈
1.在数据库中新建两张测试表 创建用户表 use eftest go if exists(select * from sysobjects where name='UserInfo') drop ta ...
- NS_ASSUME_NONNULL_BEGIN 延伸
NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END 在.h文件中,可以看到这两个宏,翻看定义,这两个宏的代码是 #define NS_ASSUME_NONNUL ...
- 《JavaScript高级程序设计》读书笔记 ---RegExp 类型
ECMAScript 通过RegExp 类型来支持正则表达式.使用下面类似Perl 的语法,就可以创建一个正则表达式.var expression = / pattern / flags ; 其中的模 ...
- Gdiplus 贴图(助记) -------------------拖动整个对话框
最简单的两种方法: 一.使WM_NCHITTEST始终返回HTCAPTION,也就是欺骗系统让他以为这是菜单栏. LRESULT CDemoDlg::OnNcHitTest(CPoint point) ...
- if和switch的原理
在C语言中,if和switch是条件分支的重要组成部分.if的功能是计算判断条件的值,根据返回的值的不同来决定跳转到哪个部分.值为真则跳转到if语句块中,否则跳过if语句块.下面来分析一个简单的if实 ...
- javaWEB总结(10):HttpServlet成长史
前言: 从Servlet,ServletConfig到GenericServlet再到Httpservlet的整个过程,相当于Httpservlet的成长史,我们不需要写那么臃肿的代码,开发难度由复杂 ...