刷水题做几道入门贪心题预热。。。
找联通块里字典序最小的放到最前面即可。记得写传递闭包
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=350;
int n,a[N],pos[N],g[N][N];
int main() {
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),pos[a[i]]=i;
char c[1100];
for(int i=1;i<=n;i++) {
scanf("%s",c);
g[i][i]=1;
for(int j=1;j<=n;j++) {
if(c[j-1]=='1') g[i][j]=1;
}
}
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
g[i][j]|=g[i][k]&g[k][j];
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++) {
if(g[i][pos[j]]) {
a[i]=j;
pos[j]=0;
break;
}
}
}
for(int i=1;i<=n;i++) printf("%d ",a[i]);
}