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("");
        }
    }
  • 相关阅读:
    JS中的函数声明存在的“先使用,后定义”
    JS原型与原型链终极详解
    Angular--页面间切换及传值的四种方法
    Angularjs Controller 间通信机制
    angularjs 中使用 service 在controller 之间 share 对象和数据
    CSS中!important的使用
    angularjs checkbox 框的操作
    纯CSS气泡框实现方法探究
    AngularJS 实现页面滚动到底自动加载数据的功能
    AngularJS的Filter用法详解
  • 原文地址:https://www.cnblogs.com/hxer/p/5276714.html
Copyright © 2011-2022 走看看