zoukankan      html  css  js  c++  java
  • [UOJ 41]【清华集训2014】矩阵变换

    Description

    给出一个 $N$ 行 $M$ 列的矩阵A, 保证满足以下性质:

    1. $M > N$。
    2. 矩阵中每个数都是 $[0, N]$ 中的自然数。
    3. 每行中, $[1, N]$ 中每个自然数都恰好出现一次。这意味着每行中 $0$ 恰好出现 $M - N$ 次。
    4. 每列中,$[1, N]$ 中每个自然数至多出现一次。

    现在我们要在每行中选取一个非零数,并把这个数之后的数赋值为这个数。我们希望保持上面的性质4,即每列中,$[1, N]$ 中每个自然数仍然至多出现一次。

    Input

    第一行一个正整数 $T$,表示数据组数。

    后面包含 $T$ 组数据,各组数据之间无空行。每组数据以两个正整数 $N, M$ 开始,接下来 $N$ 行,每行 $M$ 个用空格隔开的整数,意义如题所述。

    Output

    对于每组数据输出一行。如果有解,则输出 $N$ 个整数,依次表示每一行取的数是多少。(这应该是一个 $1$ 到 $N$ 的排列)如果无解,则输出任意卖萌表情。

    Sample Input

    2
    5 10
    0 1 0 2 3 0 0 4 0 5
    2 0 3 0 0 1 0 5 4 0
    4 2 1 0 0 0 3 0 5 0
    0 3 0 4 0 5 0 1 2 0
    1 0 0 3 2 4 5 0 0 0
    5 10
    0 1 0 2 3 0 0 4 0 5
    2 0 3 0 0 1 0 5 4 0
    4 2 1 0 0 0 3 0 5 0
    0 3 0 4 0 5 0 1 2 0
    1 0 0 3 2 4 5 0 0 0

    Sample Output

    4 5 3 1 2
    5 4 3 1 2
    

    Sample Explanation

    两组输入数据是相同的。由于结果不唯一,你可以给出任意一组合法答案。

    Hint

    对于 20% 的数据,$M < 8, T < 8$。

    对于 40% 的数据,$N < 8, T < 8$。

    对于 100% 的数据,$N < 200, M < 400, T < 50$。

    卖萌表情包括但不限于“(^o^)/” (不含引号).

    由于输入数据较大, 请自行优化输入方法.

    时间限制:$1 exttt{s}$

    空间限制:$512 exttt{MB}$

    题解

    稳定婚姻问题。

    首先值得肯定的是每一行所选的数不能相同,那么现在就相当于 $n$ 个行匹配 $n$ 个数。

    那么什么是不稳定的婚姻?如果假设数 $x$ 在第 $i$ 行选中的数之前(确保 $x$ 没有被选中的数删去),又同时选中 $x$ 的 $j$ 行中 $x$ 位置比 $i$ 行中 $x$ 位置靠前。显然这个时候是不合法的。但只要我们选第 $i$ 行的 $x$ ,再作调整就能得到合法的解。

    所以归纳得出的结论就是:在一行中,偏好选在靠前面的数字。而对于每个数字,偏好其在行中的位置靠后的行。

    那么就可以跑 $Gale-Shapley$ 。

     1 //It is made by Awson on 2018.1.18
     2 #include <set>
     3 #include <map>
     4 #include <cmath>
     5 #include <ctime>
     6 #include <queue>
     7 #include <stack>
     8 #include <cstdio>
     9 #include <string>
    10 #include <vector>
    11 #include <cstdlib>
    12 #include <cstring>
    13 #include <iostream>
    14 #include <algorithm>
    15 #define LL long long
    16 #define Abs(a) ((a) < 0 ? (-(a)) : (a))
    17 #define Max(a, b) ((a) > (b) ? (a) : (b))
    18 #define Min(a, b) ((a) < (b) ? (a) : (b))
    19 #define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
    20 #define writeln(x) (write(x), putchar('
    '))
    21 using namespace std;
    22 const int N = 200;
    23 void read(int &x) {
    24     char ch; bool flag = 0;
    25     for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
    26     for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
    27     x *= 1-2*flag;
    28 }
    29 void write(int x) {
    30     if (x > 9) write(x/10);
    31     putchar(x%10+48);
    32 }
    33 
    34 int n, m;
    35 int alike[N+5][N+5], blike[N+5][N+5];
    36 int achoice[N+5], bchoice[N+5];
    37 queue<int>Q;
    38 
    39 void work() {
    40     read(n), read(m);
    41     for (int i = 1; i <= n; i++)
    42     for (int j = 1, tot = 0, x = 0; j <= m; j++, x = 0) {
    43         read(x); if (x) alike[i][++tot] = x, blike[x][i] = j;
    44     }
    45     for (int i = 1; i <= n; i++) blike[i][n+1] = 0, bchoice[i] = n+1, achoice[i] = 1, Q.push(i);
    46     while (!Q.empty()) {
    47     int a = Q.front(), b = alike[a][achoice[a]];
    48     if (blike[b][bchoice[b]] < blike[b][a]) {
    49         Q.pop();
    50         if (bchoice[b] != n+1) {
    51         achoice[bchoice[b]]++;
    52         Q.push(bchoice[b]);
    53         }
    54         bchoice[b] = a;
    55     }else achoice[a]++;
    56     }
    57     for (int i = 1; i <= n; i++) write(alike[i][achoice[i]]), putchar(' ');
    58 }
    59 int main() {
    60     int t; read(t);
    61     while (t--) {work(); if (t) putchar('
    '); }
    62     return 0;
    63 }
  • 相关阅读:
    Linux中的yum是什么?如何配置?如何使用?
    Nginx + tornado + supervisor部署
    python3 实现mysql数据库连接池
    零代码如何打造自己的实时监控预警系统
    一步一步在Windows中使用MyCat负载均衡 上篇
    你真的会玩SQL吗?之逻辑查询处理阶段
    徒手教你制作运维监控大屏
    Jenkins+GitLab+Docker+SpringCloud+Kubernetes实现可持续自动化微服务
    容器化之Docker小知识普及
    Kubernetes知识小普及
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/8308372.html
Copyright © 2011-2022 走看看