Codeforces 541 F. Asya And Kittens(并查集+DFS)

栏目: 编程工具 · 发布时间: 6年前

内容简介:做这道题前必须会:并查集很容易想到,因为涉及到多个集合的相关操作,主要是如何模拟两个集合之间的相对位置

Codeforces 541 F. Asya And Kittens(并查集+DFS) 题目大意是说,输入$n$,表示有$n$个数$1$~$n$,接下来有$n-1$对关系,每行输入两个数$a$和$b$,表示将$a$所在的集合与$b$所在的集合合并,但是合并有前提条件,$a$所在的集合与$b$所在的集合必须相邻(数组的第一个和最后一个不算相邻)。求这组序列最开始的排列情况,答案不唯一,输出一组答案即可

做这道题前必须会: 并查集DFS

并查集很容易想到,因为涉及到多个集合的相关操作,主要是如何模拟两个集合之间的相对位置

创建一个二维邻接表 List<Integer>[] t ,$t[i]$中存放的是以$i$为根节点,所有与$i$处于同一集合的元素,因此如果合并$a$和$b$,还需要将$b$所在集合的根节点$fb$添加到$a$所在集合的根节点$fa$的邻接表中,然后将$fb$的根节点更新为$fa$。具体操作就是

fa = find(a);
fb = find(b);
t[fa].add(fb);
father[fb] = fa;

合并完了以后就要进行DFS遍历,将二维邻接表中的元素打印出来即是答案,对于样例来说,合并完以后,二维邻接表的状态如下图左边,集合(没有使用路径压缩)状态如下图右边

Codeforces 541 F. Asya And Kittens(并查集+DFS)

DFS遍历的时候进入的节点可以是任意节点的根节点,但是由于$n \geq 2$,所以最好不要寻找$x(x>3)$的根节点作为起点,因为可能$x$就根本不存在。我以1节点的根节点作为起点进行遍历,也就是 dfs(find(1)) ,那么对于上面的图来说,输出的答案应就是 31425

import java.io.BufferedInputStream;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Scanner;

public class Main {
    static int[] father;
    static ArrayList<Integer>[] t;
    static BufferedWriter print = new BufferedWriter(new OutputStreamWriter(System.out));

    static int find(int x) {
        if (father[x] == x)
            return x;
        return father[x] = find(father[x]);
    }

    static void union(int a, int b) {
        a = find(a);
        b = find(b);
        if (a != b) {
            t[a].add(b);
            father[b] = a;
        }
    }

    public static void main(String[] args) throws IOException {
        Scanner cin = new Scanner(new BufferedInputStream(System.in));
        int n = cin.nextInt();
        father = new int[n + 1];
        t = new ArrayList[n + 1];
        for (int i = 1; i <= n; i++) {
            father[i] = i;
            t[i] = new ArrayList<Integer>();
        }
        for (int i = 0; i < n - 1; i++) {
            int p = cin.nextInt();
            int q = cin.nextInt();
            union(p, q);
        }
        dfs(find(3));
        print.flush();
    }

    static void dfs(int root) throws IOException {
        print.write(root + " ");
        for (int i = 0; i < t[root].size(); i++)
            dfs(t[root].get(i));
    }
}

使用了一个输入输出优化,避免TLE


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

内容创业:内容、分发、赢利新模式

内容创业:内容、分发、赢利新模式

张贵泉、张洵瑒 / 电子工业出版社 / 2018-6 / 49

越来越多的内容平台、行业巨头、资本纷纷加入内容分发的战争中,竞争非常激烈。优质的原创性内容将成为行业中最宝贵的资源。在这样的行业形势下,如何把内容创业做好?如何提高自身竞争力?如何在这场战争中武装自己?是每一位内容创业者都应该认真考虑的问题。 《内容创业:内容、分发、赢利新模式》旨在帮助内容创业者解决这些问题,为想要进入内容行业的创业者出谋划策,手把手教大家如何更好地进行内容创业,获得更高的......一起来看看 《内容创业:内容、分发、赢利新模式》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

html转js在线工具
html转js在线工具

html转js在线工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具