【洛谷 P1653】 猴子 (并查集)
题目链接
没删除调试输出,原地炸裂,\(80\)->\(0\)。如果你要问剩下的\(20\)呢?答:数组开小了。
这题正向删边判连通性是很不好做的,因为我们并不会并查集的逆操作。于是可以考虑把断边改成逆向连边,某个猴子什么时候和\(1\)号猴子变成连通的,这就是他掉下去的时间,如果本来就与\(1\)号猴子连通,那么它就永远不会掉下去。我用了两个并查集,一个维护连通性,一个维护答案,这两个并查集前面的操作几乎是一模一样的,同时连边,到最后一步也就是某个猴子与\(1\)号猴子变为连通时,前者正常连边,后者不连,因为我们要记录原连通块里的猴子答案是一样的。然后就\(ok\)了。
#include <cstdio>
#include <cstring>
#define Open(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout);
#define Close fclose(stdin);fclose(stdout);
const int MAXN = 500010;
inline int read(){
int s = 0, w = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){ if(ch == '-') w = -1; ch = getchar();}
while(ch >= '0' && ch <= '9') { s = s * 10 + ch - '0'; ch = getchar(); }
return s * w;
}
int n, m;
int a[MAXN], b[MAXN], f[MAXN], ban[MAXN][3], F[MAXN];
int fall_time[MAXN], son[MAXN][3], start_set[MAXN], linked[MAXN];
int junk;
void init(){
for(int i = 1; i <= n; ++i)
f[i] = i;
}
int find(int x){
return f[x] == x ? x : f[x] = find(f[x]);
}
void merge(int x, int y){
f[find(y)] = find(x);
}
void Init(){
for(int i = 1; i <= n; ++i)
F[i] = i;
}
int Find(int x){
return F[x] == x ? x : F[x] = Find(F[x]);
}
void Merge(int x, int y){
F[Find(y)] = Find(x);
}
int main(){
Open("monkey");
memset(fall_time, -1, sizeof fall_time);
n = read(); m = read();
init(); Init();
for(int i = 1; i <= n; ++i){
son[i][1] = read(); son[i][2] = read();
}
for(int i = 1; i <= m; ++i){
a[i] = read(); b[i] = read();
ban[a[i]][b[i]] = 1;
}
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= 2; ++j)
if(!ban[i][j])
if(son[i][j] != -1)
merge(i, son[i][j]), Merge(i, son[i][j]);
for(int i = m; i; --i){
junk = son[a[i]][b[i]];
int fa = find(a[i]) != find(1), fb = find(junk) != find(1);
merge(a[i], junk);
if(fa && find(a[i]) == find(1))
fall_time[Find(a[i])] = i - 1;
else if(fa) Merge(a[i], junk);
if(fb && find(junk) == find(1))
fall_time[Find(junk)] = i - 1;
else if(fb) Merge(a[i], junk);
}
for(int i = 1; i <= n; ++i)
printf("%d\n", fall_time[Find(i)]);
Close;
return 0;
}
【洛谷 P1653】 猴子 (并查集)的更多相关文章
- 洛谷 P1653 猴子 解题报告
P1653 猴子 题目描述 有N只猴子,第一只尾巴挂在树上,剩下的N-1只,要么被其他的猴子抓住,要么抓住了其他的猴子,要么两者均有.当然一只猴子最多抓两只另外的猴子.现在给出这N只猴子抓与被抓的信息 ...
- 洛谷P1653 猴子
#include<bits/stdc++.h> using namespace std; inline void read(int &tmp) { ;char c=getchar( ...
- 洛谷P3295 萌萌哒 并查集 + ST表
又切一道紫题!!! 成功的(看了一吨题解之后),我A掉了第二道紫题. 好,我们仔细观察,发现这是一个排列组合问题. 有些限定条件,要相等的地方,我们就用并查集并起来.最后一查有多少个并查集,就有多少个 ...
- 洛谷P4092树——并查集
题目:https://www.luogu.org/problemnew/show/P4092 利用并查集,倒序离线,那么从倒序来看被撤销标记的点就再也不会被标记,所以用并查集跳过: 莫名其妙的WA,调 ...
- 洛谷P2391 白雪皑皑(并查集)
题目背景 “柴门闻犬吠,风雪夜归人”,冬天,不期而至.千里冰封,万里雪飘.空中刮起了鸭毛大雪.雪花纷纷,降落人间. 美能量星球(pty 在 spore 上的一个殖民地)上的人们被这美景所震撼.但是 p ...
- 洛谷P3958 奶酪 并查集
两个空洞可互达当且仅当两个空洞相切,即球心距离小于等于球的直径. 一一枚举两个可互达的空洞,并用并查集连起来即可. Code: #include<cstdio> #include<c ...
- 洛谷 P3958 奶酪 并查集
目录 题面 题目链接 题面 题目描述 输入输出格式 输入格式 输出格式: 输入输出样例 输入样例 输出样例 说明 思路 AC代码 总结 题面 题目链接 P3958 奶酪 题面 题目描述 现有一块大奶酪 ...
- 洛谷 P2391.白雪皑皑 (并查集,思维)
题意:有\(n\)个点,对这些点进行\(m\)次染色,第\(i\)次染色会把区间\((i*p+q)\ mod\ N+1\)和\((i*q+p)\ mod\ N+1\)之间的点染成颜色\(i\),问最后 ...
- 洛谷P2024食物链——并查集补集的灵活运用
题目:https://www.luogu.org/problemnew/show/P2024 自己在做本题时最大的障碍就是:不会在一个集合的father改变时把相应的补集也跟着改变. 借鉴题解后,才明 ...
随机推荐
- Bootstrap开发漂亮的前端界面之实现原理
引:Bootstrap采用的是一个“响应式”设计.响应式Web 设计是一个让用户通过各种尺寸的设备浏览网站获得良好的视觉效果的方法.例如,您先在计算机显示器上浏览一个网站,然后再智能手机上浏览,智能手 ...
- Unity3d工具方法小集
1.获取垂直水平方向上的输入: float moveHorizontal = Input.GetAxis("Horizontal"); float moveVertical = I ...
- facebook hash key
private void printHashKey() { try { PackageInfo info = getPackageManager().getPackageInfo( "xxx ...
- 《python核心编程第二版》第1章练习
1–1. 安装 Python.请检查 Python 是否已经安装到你的系统上,如果没有,请下载并 安装它 略 1–2. 执行 Python.有多少种运行 Python 的不同方法?你喜欢哪一种?为什 ...
- ubuntu 开热点
原文地址:https://www.cnblogs.com/king-ding/archive/2016/10/09/ubuntuWIFI.html 今天教大家一个简单方法让ubuntu发散wifi热点 ...
- LeetCode 33——搜索旋转排序数组
1. 题目 2. 解答 2.1. 方法一 直接进行二分查找,在判断查找方向的时候详细分类. 当 nums[mid] < target 时, 若 nums[left] <= nums[mid ...
- Python3 初识Python
一 Python简介 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC ...
- C++-STL:vector用法总结
目录 简介 用法 1. 头文件 2. vector的声明及初始化 3. vector基本操作 简介 vector,是同一类型的对象的集合,这一集合可看作可变大小的数组,是顺序容器的一种.相比于数组,应 ...
- 面试题中经常遇到的SQL题:删除重复数据,保留其中一条
如题,解决思路如下: 1.首先我们需要找出拥有重复数据的记录 ---以name字段分组 select Name,COUNT(Name) as [count] from Permission group ...
- 时间戳转换成日期的js
在项目开发过程中,我们常常需要把时间戳转换成日期.下面这个是我一直使用的js方法,希望能帮助到有需要的朋友.大家如果有更好的方法,请多多指教! js代码如下: //时间戳转换成日期 function ...