zoukankan      html  css  js  c++  java
  • Codeforces 650C Table Compression (并查集)

    题意:M×N的矩阵 让你保持每行每列的大小对应关系不变,将矩阵重写,重写后的最大值最小。

    思路:离散化思想+并查集,详见代码

    好题!

     1 #include <iostream>
     2 #include <string.h>
     3 #include <stdio.h>
     4 #include <algorithm>
     5 #include <cmath>
     6 #include <cstdlib>
     7 #include <bits/stdc++.h>
     8 using namespace std;
     9 #define clc(a,b) memset(a,b,sizeof(a))
    10 const double pi=acos(-1);
    11 const int maxn=1000010;
    12 int k,n,m,tot,i,j;
    13 struct data {
    14     int r,c,v,id;
    15 } p[maxn];
    16 bool cmp(const data &a,const data &b) {
    17     return a.v<b.v;
    18 }
    19 int f[maxn],X[maxn],Y[maxn],x[maxn],y[maxn],ans[maxn],tmp[maxn];
    20 
    21 int F(int a) {
    22     return a==f[a]?f[a]:f[a]=F(f[a]);
    23 }
    24 
    25 int main() {
    26     //freopen("in.txt","r",stdin);
    27     scanf("%d%d",&n,&m);
    28     tot=0;
    29     clc(tmp,0);
    30     clc(f,-1);
    31     for( i=1; i<=n; i++) {
    32         for( j=1; j<=m; j++) {
    33             scanf("%d",&p[++tot].v);
    34             p[tot].r=i,p[tot].c=j;
    35             p[tot].id=tot;
    36             f[tot]=tot;
    37         }
    38     }
    39     sort(p+1,p+1+tot,cmp);
    40     for(i=1; i<=tot; i=j) {
    41         for(j=i; p[i].v==p[j].v; j++);//每次只处理相同元素
    42         for(k=i; k<j; k++) {//每行每列并查集统计,归并到一个集合
    43             int r=p[k].r,c=p[k].c;
    44             if(!x[r]) x[r]=k;
    45             else
    46                 f[F(k)]=F(x[r]);
    47             if(!y[c]) y[c]=k;
    48             else
    49                 f[F(k)]=F(y[c]);
    50         }
    51         for(k=i; k<j; k++) {//当前值的改变值 应该是该元素所在行或列 前一个填入的值再加一
    52             int q=F(k);
    53             tmp[q]=max(tmp[q],max(X[p[k].r],Y[p[k].c])+1);
    54         }
    55         for(k=i; k<j; k++) {//X Y数组维护行和列的最大填入值
    56             x[p[k].r]=y[p[k].c]=0;
    57             X[p[k].r]=Y[p[k].c]=ans[p[k].id]=tmp[F(k)];
    58         }
    59     }
    60     for(i=1; i<=tot; i++) {
    61         if(i%m==1)
    62             printf("%d",ans[i]);
    63         else
    64             printf(" %d",ans[i]);
    65         if(i%m==0)
    66             printf("
    ");
    67     }
    68     return 0;
    69 }
    View Code
  • 相关阅读:
    天国近了(一) 揭穿OOP神话
    自然思考:流程任意定制的一个问题
    风水占卜是迷信吗?
    飘浮的鸡蛋壳真正的原理研究
    ListView
    Java与WCF交互(一):Java客户端调用WCF服务 (转)
    WPF ListView 数据绑定
    .NET中Trace类和Debug类的应用举例(转)
    Print Visual Tree
    EntityFramework之领域驱动设计实践(六)(转)
  • 原文地址:https://www.cnblogs.com/ITUPC/p/5343472.html
Copyright © 2011-2022 走看看