CF500B New Year Permutation

贪心

题意是你有一个数列,一些位置之间可以互换,问你能得到的最小序列是多少

我们发现一个数能换到另一个地方,那么还能换到这个位置能去的地方,所以我们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;
}

猜你喜欢

转载自blog.csdn.net/acerandaker/article/details/81064547