Good Bye 2014 B. New Year Permutation(贪心+Floyd)

Description
给出一个长度为n的序列p和一个n*n的矩阵A,如果A[i][j]=1,那么pi和p可以互换,输出经过一系列变换后字典序最小的p序列
Input
第一行为一整数n表示序列长度,第二行n个整数表示p序列,之后为一个n*n的01矩阵A
Output
输出经过变换后字典序最小的p序列
Sample Inout
7
5 2 4 3 6 7 1
0001001
0000000
0000010
1000001
0000000
0010000
1001000
Sample Output
1 2 4 3 6 7 5
Solution
首先跑一遍Floyd求出A矩阵的传递闭包以得到各点之间的可达情况,之后贪心的在前面的位置上放较小的数
Code

#include<cstdio>
#include<iostream>
using namespace std;
#define maxn 333
int n,p[maxn],A[maxn][maxn];
char a[maxn][maxn];
int main()
{
    while(~scanf("%d",&n))
    {
        for(int i=1;i<=n;i++)
            scanf("%d",&p[i]);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",a[i]+1);
            for(int j=1;j<=n;j++)
                A[i][j]=a[i][j]-'0';
        }
        for(int k=1;k<=n;k++)
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    if(A[i][k]&&A[k][j])
                        A[i][j]=1;

        for(int i=1;i<n;i++)
            for(int j=i+1;j<=n;j++)
                if(p[i]>p[j]&&A[i][j])
                {
                    int t=p[i];
                    p[i]=p[j];
                    p[j]=t;
                }
        for(int i=1;i<=n;i++)
            printf("%d%c",p[i],i==n?'\n':' ');
    }
    return 0;
}

你可能感兴趣的:(Good Bye 2014 B. New Year Permutation(贪心+Floyd))