zoukankan      html  css  js  c++  java
  • codeforces Codeforces Round #345 (Div. 1) C. Table Compression 排序+并查集

    C. Table Compression

    Little Petya is now fond of data compression algorithms. He has already studied gz, bz, zip algorithms and many others. Inspired by the new knowledge, Petya is now developing the new compression algorithm which he wants to name dis.

    Petya decided to compress tables. He is given a table a consisting of n rows and m columns that is filled with positive integers. He wants to build the table a' consisting of positive integers such that the relative order of the elements in each row and each column remains the same. That is, if in some row i of the initial table ai, j < ai, k, then in the resulting table a'i, j < a'i, k, and if ai, j = ai, k then a'i, j = a'i, k. Similarly, if in some column j of the initial table ai, j < ap, j then in compressed table a'i, j < a'p, j and if ai, j = ap, j then a'i, j = a'p, j.

    Because large values require more space to store them, the maximum value in a' should be as small as possible.

    Petya is good in theory, however, he needs your help to implement the algorithm.

    Input

    The first line of the input contains two integers n and m (, the number of rows and the number of columns of the table respectively.

    Each of the following n rows contain m integers ai, j (1 ≤ ai, j ≤ 109) that are the values in the table.

    Output

    Output the compressed table in form of n lines each containing m integers.

    If there exist several answers such that the maximum number in the compressed table is minimum possible, you are allowed to output any of them.

    Examples
    Input
    2 2
    1 2
    3 4
    Output
    1 2
    2 3
    Input
    4 3
    20 10 30
    50 40 30
    50 60 70
    90 80 70
    Output
    2 1 3
    5 4 3
    5 6 7
    9 8 7
    Note

    In the first sample test, despite the fact a1, 2 ≠ a21, they are not located in the same row or column so they may become equal after the compression.

    题意:个数不超过1e6个数的二维数列;按照行与列数的相对大小尽可能的缩小为正整数,但不在同一行或同一列的数的缩放前后的大小没有关系;

    输出缩放后的数列;

    思路:排序后每次处理都是处理值相等的一串数据,并且是看成没没有填入到新数组中,这样使用并查集就可以得到“十”字形相等的根节点的最大值,即所有这棵并查集下的节点的值;x[i],y[i]来模拟并查集,X[],Y[]表示行列上一个值填到的数值,所以之后直接得到根节点所要填入的值;

    #include<bits/stdc++.h>
    using namespace std;
    int i,j,k,n,m,T,tot;
    const int N = 1000100;
    struct data{
        int r,c,v,id;
    }p[N];
    bool cmp(const data &a,const data &b){return a.v < b.v;}
    int f[N],X[N],Y[N],ans[N],x[N],y[N],tmp[N];
    int Find(int a){return a==f[a]?f[a]:f[a]=Find(f[a]);}
    int main()
    {
        scanf("%d%d",&n,&m);
        for(i = 1;i <= n;i++)
        for(j = 1;j <= m;j++){
            scanf("%d",&p[++tot].v);
            p[tot].r = i,p[tot].c = j;
            p[tot].id = tot;
            f[tot] = tot;
        }
        sort(p+1,p+1+tot,cmp);
        for(i = 1;i <= tot;i = j){
            for(j = i;p[i].v == p[j].v;++j);
            for(k = i;k < j;k++){
                int r = p[k].r, c = p[k].c;
                if(!x[r]) x[r] = k;// 行并查
                else f[Find(k)] = Find(x[r]);
                if(!y[c]) y[c] = k;
                else f[Find(k)] = Find(y[c]);//f[k]会因为十字型交叉而出错;
            }
            for(k = i;k < j;k++){//只是在之前的值的基础上得到,不是模拟填入值
                int q = Find(k);
                tmp[q] = max(tmp[q],max(X[p[k].r],Y[p[k].c])+1);
            }
            for(k = i;k < j;k++){//根节点得到的是全体的值
                x[p[k].r] = y[p[k].c] = 0;
                X[p[k].r] = Y[p[k].c] = ans[p[k].id] = tmp[Find(k)];
            }
        }
        for(i = 1;i <= tot;i++){
            printf("%d ",ans[i]);
            if(i%m == 0) puts("");
        }
    }
  • 相关阅读:
    .Net开发中IIS启动后,网站不能访问。0x80004005 无法执行程序。所执行的命令为 .....问题
    .Net开发中项目无法引用/项目引用失败/引用文件出现黄色警告图标,并生成失败的问题
    Mac系统安装Docker
    小程序开发----微信小程序实现下拉刷新功能
    小程序开发----微信小程序navigate跳转没反应
    小程序开发----小程序点击复制文本内容到剪贴板
    小程序开发----微信小程序直接写&nbsp;设置空格无效
    python字符串的反转
    python2项目迁移到python3
    robotframework废弃的关键词以及替代的关键词(关键词找不到,可能已经过期了)
  • 原文地址:https://www.cnblogs.com/hxer/p/5276714.html
Copyright © 2011-2022 走看看