[CodeForces500B]New Year Permutation[floyd]

来源:互联网 发布:淘宝活动工具 编辑:程序博客网 时间:2024/05/10 17:33

题目链接:[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;}

0 0
原创粉丝点击