AtCoder Beginner Contest 279 F BOX 并查集 (大意失荆州
创始人
2024-02-21 15:15:40

前言

赛时一直RE,思路很清晰,不知道RE哪里。。qwq
赛后开断点发现,map的大小不变,
最后发现是一个if条件写错了,寄。

不知道为什么会想起 银河英雄传说

题意:

初始n个盒子,盒子iii放着编号为iii的小球
进行q次操作

  • op1:将y盒子的小球移到x盒子中
  • op2:将第k个球,加入到x盒子中
  • op3:询问球x在哪个盒子中

思路:

我们看到op1,联想到集合的合并,于时想到并查集的操作在这里插入图片描述
图中绿色的点代表盒子。

  1. 经过 多个op1,op1,op1…我们可以用并查集把这些合并到盒子2
  2. 此时,突然有个 op112op_1 \ 1 \ 2op1​ 1 2, 那么我们merge(box[1],box[2])merge(box[1],box[2])merge(box[1],box[2])
merge(int x, int y){int fx = find(x), fy = find(y);p[fy] = fx;//根据题意合并
}
  1. 误区:此时突然来个op22op_2 \ 2op2​ 2,

假如新球,连到原来的盒子p[k] = find(box[2]) ,最后会使得新球在盒子1其实新球在盒子2

因为p[box[2]] == p[box[1]]

做法

  • 对于每个盒子和点都编号
  • 每次操作1后,把yyy盒子删除,新建一个y‘y `y‘
box[y] = ++newBox;

What’s more

看了SSRS,好像可以用启发式合并,一开始我也是想用,但后面发现新开点,就可以解决了。

Java

package com.hgs.atcoder.abc.contest279.f;/*** @author youtsuha* @version 1.0* Create by 2022/11/26 19:43*/
import java.util.*;
import java.io.*;
public class Main{static FastScanner cin;static PrintWriter cout;private static void init()throws IOException {cin = new FastScanner(System.in);cout = new PrintWriter(System.out);}private static void close(){cout.close();}static int[] p;static int find(int x){if(x == p[x]) {return p[x];}return p[x] = find(p[x]);}private static void sol()throws IOException {int n = cin.nextInt(), m = cin.nextInt();int tot = n  + m;p = new int[tot*2 + 1];Map curBox = new HashMap<>();Map boxPre = new HashMap<>();int newBox = tot;//[1,tot] balls//[tot+1,tot*2] boxsfor(int i = 1; i <= tot*2; i ++ ) {p[i] = i;if(i > tot && i <= tot + n){newBox++;curBox.put(i - tot,i);boxPre.put(i,i-tot);}else if(i <= n){p[i] = i + tot;}}int k = n;for(int i = 1; i <= m; i ++ ) {int op = cin.nextInt(), x = cin.nextInt();if(op == 1){int y = cin.nextInt();//y-->xint preY = curBox.get(y);p[preY] = p[curBox.get(x)];boxPre.put(++newBox,y);curBox.put(y,newBox);}else if(op == 2){k++;p[k] = curBox.get(x);}else {cout.println(boxPre.get(find(p[x])));}}}public static void main(String[] args) throws IOException {init();sol();close();}
}
class FastScanner {BufferedReader br;StringTokenizer st = new StringTokenizer("");public FastScanner(InputStream s) {br = new BufferedReader(new InputStreamReader(s));}public FastScanner(String s) throws FileNotFoundException {br = new BufferedReader(new FileReader(new File(s)));}public String next() throws IOException {while (!st.hasMoreTokens()){try {st = new StringTokenizer(br.readLine());} catch (IOException e) { e.printStackTrace(); }}return st.nextToken();}public int nextInt() throws IOException {return Integer.parseInt(next());}public long nextLong() throws IOException {return Long.parseLong(next());}public double nextDouble() throws IOException {return Double.parseDouble(next());}
}

相关内容

热门资讯

《放翁家训》原文及翻译 《放翁家训》原文及翻译  导语:陆游一生笔耕不辍,诗词文俱有很高成就,其诗语言平易晓畅、章法整饬谨严...
教师个人师德事迹材料 教师个人师德事迹材料  本人任教九年级历史、政治,八年级历史等学科,能够全面贯彻国家教育方针路线和精...
苏轼《水调歌头》原文 苏轼《水调歌头》原文  《水调歌头·明月几时有》是宋代大文学家苏轼公元1076年(宋神宗熙宁九年)中...
“特马互掐”或成致命一击?知名... 财联社7月3日讯(编辑 黄君芝)最近几天,特斯拉CEO马斯克和美国总统特朗普再度因“大而美”法案爆发...
普祥健康拟上市:董事长小18岁... 瑞财经 刘治颖 6月30日,普祥健康控股有限公司(以下简称“普祥健康”)向港交所首次呈交上市申请文件...