题意
给你 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;
}
学如逆水行舟,不进则退