[CodeForces500B]New Year Permutation[floyd]

题目链接:[CodeForces500B]New Year Permutation[floyd]

题意分析:矩阵中s[i][j] == '1' 时,对应的a[i], a[j]可进行互换,问:根据矩阵,多次互换后最终可以得到字典序最小的序列是什么?

解题思路:既然要求字典序最小,那就尽量把小的往前排。那么怎么样尽量往前排呢?就是遍历所以该点能到达的点,让最小的,并且排在这个点后面的点与它交换即可。怎样遍历到所有能到达的点呢?这个时候就要用到floyd了。

个人感受:表示题意好难懂TAT。然后遍历所有能到的点,之前想的是dfs,然后各种debug。还是floyd大法好呀~

具体代码如下:

#include <iostream>
#include <cstdio>
using namespace std;

const int MAXN = 310;
int a[MAXN];
char s[MAXN][MAXN];

int main() {
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; ++i)
        scanf("%d", a + i);
    for (int i = 0; i < n; ++i)
        scanf("%s", s[i]);
    
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
            for (int k = 0; k < n; ++k)
                if (s[j][i] == '1' && s[i][k] == '1') //没有必要硬去记什么在内什么在外,只要记住最外层代表的是中间的连接点,floyd就很好记的
                    s[j][k] = '1';
    
    for (int i = 0; i < n; ++i)
    {
        int mi = a[i]; //记录最小值
        int p = i;     //记录最小值对应的坐标
        for (int j = 0; j < n; ++j)
        {
            if (s[i][j] == '1' && mi > a[j] && p < j)  //值小,且排在后面的点
            {
                mi = a[j];
                p = j;
            }
        }
        swap(a[i], a[p]);
    }
    for (int i = 0; i < n - 1; ++i)
        printf("%d ", a[i]);
    printf("%d\n", a[n - 1]);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值