• Educational Codeforces Round 14 D. Swaps in Permutation 并查集


    D. Swaps in Permutation

    题目连接:

    http://www.codeforces.com/contest/691/problem/D

    Description

    You are given a permutation of the numbers 1, 2, ..., n and m pairs of positions (aj, bj).

    At each step you can choose a pair from the given positions and swap the numbers in that positions. What is the lexicographically maximal permutation one can get?

    Let p and q be two permutations of the numbers 1, 2, ..., n. p is lexicographically smaller than the q if a number 1 ≤ i ≤ n exists, so pk = qk for 1 ≤ k < i and pi < qi.

    Input

    The first line contains two integers n and m (1 ≤ n, m ≤ 106) — the length of the permutation p and the number of pairs of positions.

    The second line contains n distinct integers pi (1 ≤ pi ≤ n) — the elements of the permutation p.

    Each of the last m lines contains two integers (aj, bj) (1 ≤ aj, bj ≤ n) — the pairs of positions to swap. Note that you are given a positions, not the values to swap.The only line contains the positive decimal number x. The length of the line will not exceed 106. Note that you are given too large number, so you can't use standard built-in data types "float", "double" and other.

    Output

    Print the only line with n distinct integers p'i (1 ≤ p'i ≤ n) — the lexicographically maximal permutation one can get.

    Sample Input

    9 6
    1 2 3 4 5 6 7 8 9
    1 4
    4 7
    2 5
    5 8
    3 6
    6 9

    Sample Output

    7 8 9 4 5 6 1 2 3

    Hint

    题意

    给你一个排列,和m个可以交换的关系

    然后你只能交换这m对关系,你可以交换无限次

    问你,你能够得到的最大字典序的串是什么

    题解:

    把能够交换得到的位置用并查集维护,然后对于每个位置,把能够放的最大值扔上去就好了

    代码

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn = 1e6+7;
    int fa[maxn],n,m;
    int fi(int x){
        if(x==fa[x])return x;
        return fa[x]=fi(fa[x]);
    }
    vector<int> E[maxn];
    int t[maxn];
    bool cmp(int a,int b){
        return a>b;
    }
    int a[maxn];
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            fa[i]=i;
        }
        for(int i=1;i<=m;i++){
            int x,y;scanf("%d%d",&x,&y);
            fa[fi(x)]=fi(y);
        }
        for(int i=1;i<=n;i++){
            E[fi(i)].push_back(a[i]);
        }
        for(int i=1;i<=n;i++){
            sort(E[i].begin(),E[i].end(),cmp);
        }
        for(int i=1;i<=n;i++){
            printf("%d ",E[fi(i)][t[fi(i)]++]);
        }
    }
  • 相关阅读:
    AxWindowsMediaPlayer的详细用法
    C# 播放器控件的常用方法
    在 C# 中使用文件名启动应用程序
    备份和恢复Android手机的NAND分区
    刷Recovery的方法
    WPF RadioButton的探究,为啥选中一个其他都自动不选中了呢?
    WPF大牛Josh Smith 转投 iOS 的怀抱
    终端服务的剪贴板的缺陷,导致WPF调用Clipboard.SetText() 失败
    用df命令查看分区情况
    WPF与输入法冲突研究之二:TextInput事件的BUG?
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5725956.html
Copyright © 2020-2023  润新知