Codeforces Round #345 (Div. 1) C. Table Compression

题目链接

先从小到大去排个序

想着记录每行每列当前最大值,然后就取两者最大值+1就行了

但是相同的数字因为行列不一,条件也不一样苛刻,所以要是能修改的时候把所有相同的数字也修改就好了

所以并查集,只关心根节点的值就好了

这里想漏了一点,并不是所有相同的数字都要相同,因为他们其实互不管辖,除了同行同列的相同数字。

#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>
#include <map>
#include <utility>
using namespace std;

#define MAXN 1000005

int f[MAXN],Size[MAXN],val[MAXN];

int find(int x) {
    return f[x]==x ? x : f[x] = find(f[x]);
}

inline void merge(int x,int y) {
    int fx = find(x), fy = find(y);
    if(fx==fy) return;
    if(Size[fx]<Size[fy]) f[fx] = fy,Size[fy] += Size[fx];
    else f[fy] = fx,Size[fx] += Size[fy];
}

struct Node {
    int num,x,y,pos;
} a[MAXN];

inline bool cmp1(const Node& x, const Node& y) {
    return x.num<y.num;
}

inline bool cmp2(const Node& x, const Node& y) {
    if(x.x==y.x) return x.num<y.num;
    return x.x < y.x;
}

inline bool cmp3(const Node& x, const Node& y) {
    if(x.y==y.y) return x.num<y.num;
    return x.y < y.y;
}

int X[MAXN],Y[MAXN];
int tot = 0;

int main() {

    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int N,M; cin >> N >> M;


    for(int i=1;i<=N*M;++i) {
        f[i] = i; Size[i] = 1;
    }

    for(int i=1;i<=N;++i) {
        for(int j=1;j<=M;++j) {
            cin >> a[(i-1)*M+j].num; 
            a[(i-1)*M+j].x = i; a[(i-1)*M+j].y = j;
            a[(i-1)*M+j].pos = (i-1)*M+j;
        }
    }

    sort(a+1,a+1+N*M,cmp2);

    for(int i=2;i<=N*M;++i) {
        if(a[i].x==a[i-1].x&&a[i].num==a[i-1].num) merge(a[i].pos,a[i-1].pos);
    }

    sort(a+1,a+1+N*M,cmp3);
    for(int i=2;i<=N*M;++i) {
        if(a[i].y==a[i-1].y&&a[i].num==a[i-1].num) merge(a[i].pos,a[i-1].pos);
    }

    sort(a+1,a+1+N*M,cmp1);
    for(int i=1;i<=N*M;++i) {
        
        int fx = find(a[i].pos);
        if(X[a[i].x]==0&&Y[a[i].y]==0) {
            if(val[fx]==0) val[fx] = 1;
        }
        else {
            if(fx!=X[a[i].x]) val[fx] = max(val[fx],val[find(X[a[i].x])]+1);
            if(fx!=Y[a[i].y]) val[fx] = max(val[fx],val[find(Y[a[i].y])]+1);
        }
        X[a[i].x] = Y[a[i].y] = fx; 
    }

    for(int i=1;i<=N;++i) {
        for(int j=1;j<=M;++j) cout << val[find((i-1)*M+j)] << " ";
        cout << "\n";
    }
    return 0;
}
posted @ 2021-12-02 14:05  Neworld1111  阅读(35)  评论(0编辑  收藏  举报