• UOJ #41. 【清华集训2014】矩阵变换


    #41. 【清华集训2014】矩阵变换

    链接

    分析:

      神题!

      这题可以转化为稳定婚姻问题。每行喜欢出现尽量靠左的数,每个数喜欢它出现位置(这个数在这行中出现的位置)尽量靠右的行。要求每一行匹配一个数,每一个数匹配一行。

      稳定婚姻问题中不合法的匹配是指:对于每一个人,在他心目中比他当前的伴侣更好的异性,都不会认为他也是一个更好的选择。(摘自Matrix67)。

      可以发现,此题的不合法匹配(一列中出现两个相同的数)与稳定婚姻问题的不合法匹配相似。

      即在一行中选择一个数是合法匹配,那么这个数在当前位置的右边没有这个数的行(更优的行,保证满足条件),如果一个数选择了一个行,那么其他行的这个数的位置的右边是没有这个数。  

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 
     5 inline int read() {
     6     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
     7     for (;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
     8 }
     9 
    10 const int N = 510;
    11 int order[N][N],pref[N][N],cur[N],cnt[N],Boys[N],Girls[N];
    12 int a[N][N],q[50010],L,R; // q的数据范围!!! 
    13 
    14 void Link(int u,int v) {
    15     int t = Girls[v];
    16     if (t) {
    17         Boys[t] = 0;
    18         q[++R] = t;
    19     }
    20     Boys[u] = v;
    21     Girls[v] = u;
    22 }
    23 void solve() {
    24     int n = read(),m = read();
    25     L = 1,R =  0;
    26     memset(Boys,0,sizeof(Boys));
    27     memset(Girls,0,sizeof(Girls));
    28     memset(cnt,0,sizeof(cnt));
    29     for (int i=1; i<=n; ++i) {
    30         cur[i] = 1;
    31         q[++R] = i;
    32         int p = 0;
    33         for (int j=1; j<=m; ++j) {    
    34             a[i][j] = read();
    35             if (a[i][j]) pref[i][++p] = j;
    36         }
    37     }
    38     for (int j=m; j>=1; --j) {
    39         for (int i=1; i<=n; ++i) {
    40             if (a[i][j]) order[a[i][j]][i] = ++cnt[a[i][j]];
    41         }
    42     }
    43     while (L <= R) {
    44         int u = q[L++];
    45         int v = a[u][pref[u][cur[u]++]];
    46         if (!Girls[v]) Link(u,v);
    47         else if (order[v][u] < order[v][Girls[v]]) Link(u,v);
    48         else q[++R] = u;
    49     }
    50     for (int i=1; i<=n; ++i) 
    51         printf("%d ",Boys[i]);
    52     puts("");
    53 }
    54 int main() {
    55     int Case = read();
    56     while (Case--) solve();    
    57     return 0;
    58 }
  • 相关阅读:
    HDU-5980
    HDU-5974
    HDU-5979
    关于position的定位
    javascript学习笔记w3chool
    表单相关css技巧
    fis压缩工具的使用
    将HTML页面内容存入json数组
    中介PHP连接前台HTML与数据库MySQL
    lesscss的使用
  • 原文地址:https://www.cnblogs.com/mjtcn/p/9276852.html
Copyright © 2020-2023  润新知