贪心
题意是你有一个数列,一些位置之间可以互换,问你能得到的最小序列是多少
我们发现一个数能换到另一个地方,那么还能换到这个位置能去的地方,所以我们floyd传递闭包,求出所有能换到的地方,然后每位使用它能用的最小的数,已经使用过就后移
代码
//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=500;
int n,a[M];
int map[M][M];
inline int read()
{
int x=0;char ch=getchar();
while (ch>'9'||ch<'0') ch=getchar();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x;
}
inline void floyd()
{
for (int k=1;k<=n;k++)
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
map[i][j]=((map[i][k]&map[k][j])|map[i][j]);
return ;
}
int main()
{
n=read();char s[M][M];
for (int i=1;i<=n;i++) a[i]=read();
for (int i=1;i<=n;i++) scanf("%s",s[i]+1);
for (int i=1;i<=n;i++)
for (int k=1;k<=n;k++)
map[i][k]=(i==k?1:s[i][k]-'0');
floyd();
for(int i=1;i<n;i++)
for(int k=i+1;k<=n;k++)
if(a[i]>a[k]&&map[i][k])
{int t=a[i];a[i]=a[k],a[k]=t;}
for (int i=1;i<=n;i++) cout<<a[i]<<" ";
return 0;
}