zoukankan      html  css  js  c++  java
  • CF1131F Asya And Kittens 题解

    Description

    洛谷传送门

    Solution

    感觉题解区的各位大佬代码都写麻烦了(sto @SGColin 学长 orz)。

    还是并查集的做法,但是连边的时候直接连即可。

    首先开 (n) 个 vector,假设当前要让联通快 (x)(y) 相邻((x)(y) 不在同一个联通快内),我们直接把 find(y) 插入到 g[find(x)] 即可。

    也就是 g[find(x)].push_back(find(y));

    输出时,先随便 find 一个点(此时所有点已经在同一联通块中了,所以可以随意 find),然后枚举这个点的 vector,递归输出。

    考虑正确性,由于我们是按顺序合并的,所以 vector 中排名靠前的和当前点挨得更近,且 vector 中的每一个点都是一个联通块,所以递归输出。

    代码就很简单啦。

    Code

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <vector>
    
    using namespace std;
    
    const int N = 2e5;
    int n;
    int f[N];
    vector <int> g[N];
    
    inline int find(int x){
        return f[x] == x ? x : f[x] = find(f[x]);
    }
    
    inline void print(int s){
        for(auto x : g[s]){
            printf("%d ", x);
            if(g[x].size()) print(x);
        }
    }
    
    int main(){
        scanf("%d", &n);
        for(int i = 1; i <= n; ++i)
            f[i] = i;
        for(int i = 1, x, y; i < n; ++i){
            scanf("%d%d", &x, &y);
            int fx = find(x), fy = find(y);
            if(fx != fy){
                f[fy] = fx;
                g[fx].push_back(fy);
            }
        }
        int s = find(1);
        printf("%d ", s);
        print(s);
        puts("");
        return 0;
    }
    

    End

    本文来自博客园,作者:xixike,转载请注明原文链接:https://www.cnblogs.com/xixike/p/15499644.html

  • 相关阅读:
    Android 手势&触摸事件
    vim常用命令总结
    关于背景中的雪花
    博客园美化——看板娘
    组合数
    扩展欧几里得和求逆元
    dfs序
    RMQ问题
    NOIP2017 列队
    线段树详解
  • 原文地址:https://www.cnblogs.com/xixike/p/15499644.html
Copyright © 2011-2022 走看看