Good Bye 2014, problem: (B) New Year Permutation 【并查集】

题意

给你 n 个数字的序列,然后给你 n 行字符串,如果第 i 行字符串对应的第 j 列的字符是1,说明序列 i 和 j 对应的数字可以互换,求所能互换的最小字典序的序列

思路

并查集,输入每行的时候,如果对应的列是1,就把该行和该列用并查集连接起来,然后再遍历序列的每一个数字,把属于一个联通块的数字进行比较

code

#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
const int maxn=310;
char mp[maxn];
int n;
int p[maxn];
int fa[maxn];
int findFa(int x){
    if(x!=fa[x])
        fa[x]=findFa(fa[x]);
    return fa[x];
}
void join(int x,int y){
    int a=findFa(x);
    int b=findFa(y);
    if(a!=b)
        fa[a]=b;
}
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>p[i];
        fa[i]=i;
    }
    for(int i=1;i<=n;i++){
        scanf("%s",mp+1);
        for(int j=1;j<=n;j++){
            if(mp[j]=='1')
                join(i,j);
        }
    }
    for(int i=1;i<=n;i++){
        int tmp=i;
        for(int j=i+1;j<=n;j++){
            if(findFa(i)==findFa(j)&&p[j]<p[i]){
                tmp=j;
                swap(p[i],p[tmp]);
            }
        }
    }
    for(int i=1;i<=n;i++)
        cout<<p[i]<<" ";
    cout<<endl;
    return 0;
}
学如逆水行舟,不进则退
发布了420 篇原创文章 · 获赞 982 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/weixin_42429718/article/details/104113595