题目链接:

E. Table Compression

time limit per test

4 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

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 题意: 给一个n*m的矩阵,要你在不该变任意一行或一列中两个数的大小关系使得这个矩阵的最大值最小; 思路: 假设这些数全部都不相等,那么我们可以排序后再按从小到大的顺序插入到原来的位置上,插入的是这个位置所在行和列的最大数+1,而现在其中有些数相同,
思考后可知,相等的数不在同行或同列时互相没有影响,跟上述插入方式一样,但是如果在同行或者同列,那么位置插入的数的大小应该相同,且是这些位置的所在行和列的最大值+1;
所以我们把在同行或者同列的相同的数放在一个集合里面,改变一个的时候全部改变,这就可以用并查集了;
具体的实现看代码; AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <bits/stdc++.h>
#include <stack>
#include <map> using namespace std; #define For(i,j,n) for(int i=j;i<=n;i++)
#define mst(ss,b) memset(ss,b,sizeof(ss)); typedef long long LL; template<class T> void read(T&num) {
char CH; bool F=false;
for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
F && (num=-num);
}
int stk[70], tp;
template<class T> inline void print(T p) {
if(!p) { puts("0"); return; }
while(p) stk[++ tp] = p%10, p/=10;
while(tp) putchar(stk[tp--] + '0');
putchar('\n');
} const LL mod=1e9+7;
const double PI=acos(-1.0);
const int inf=1e9;
const int N=1e6+120;
const int maxn=210;
const double eps=1e-12; int n,m,a[N],p[N],l[N],r[N],vis[N],ans[N];
vector<int>ve[N];
struct node
{
int a,id,i,j;
}po[N];
int cmp1(node x,node y)
{
if(x.a==y.a)return x.i<y.i;
return x.a<y.a;
}
int cmp2(node x,node y)
{
if(x.a==y.a)return x.j<y.j;
return x.a<y.a;
}
int findset(int x)
{
if(p[x]==x)return x;
return p[x]=findset(p[x]);
}
int same(int x,int y)
{
int fx=findset(x),fy=findset(y);
if(fx<fy)p[fy]=fx;
else if(fx>fy)p[fx]=fy;
} int main()
{
int cnt=0;
read(n);read(m);
For(i,0,n*m)p[i]=i;
For(i,1,n)
{
For(j,1,m)
{
cnt++;
po[cnt].id=cnt;
po[cnt].i=i;po[cnt].j=j;
read(po[cnt].a);
}
}
sort(po+1,po+cnt+1,cmp2);//两次排序把在同行和同列的相同的数合并
For(i,2,cnt)
{
if(po[i].a==po[i-1].a&&po[i].j==po[i-1].j)same(po[i].id,po[i-1].id);
}
sort(po+1,po+cnt+1,cmp1);
For(i,2,cnt)
{
if(po[i].a==po[i-1].a&&po[i].i==po[i-1].i)same(po[i].id,po[i-1].id);
}
For(i,1,cnt)//可以由root找到这个集合所有数所在的位置;
{
int root=findset(po[i].id);
ve[root].push_back(i);
}
For(i,1,cnt)
{
int root=findset(po[i].id);
if(!vis[root])
{
int temp=0,len=ve[root].size();//对root一次操作改变这个集合里面所有元素的答案;
for(int j=0;j<len;j++)
{
int x=ve[root][j];
temp=max(temp,r[po[x].i]);
temp=max(temp,l[po[x].j]);
}
temp++;ans[root]=temp;
for(int j=0;j<len;j++)
{
int x=ve[root][j];
l[po[x].j]=r[po[x].i]=temp;
}
vis[root]=1;
}
ans[po[i].id]=ans[root];
}
For(i,1,n)
{
For(j,1,m-1)printf("%d ",ans[(i-1)*m+j]);
printf("%d\n",ans[i*m]);
}
return 0;
}

  

codeforces 651E E. Table Compression(贪心+并查集)的更多相关文章

  1. Codeforces #345div1 C Table Compression (650C) 并查集

    题意:给你一个n*m的矩阵,需要在不改变每一行和每一列的大小关系的情况下压缩一个矩阵,压缩后的矩阵所有数的总和尽量的小. 思路:我们有这样的初步设想:对于在一行或一列的数x,y,若x<y,则建立 ...

  2. Codeforces 651E Table Compression【并查集】

    题目链接: http://codeforces.com/problemset/problem/650/C 题意: 给定n*m的矩阵,要求用最小的数表示每个元素,其中各行各列的大小关系保持不变. 分析: ...

  3. Codeforces Round #345 (Div. 1) C. Table Compression dp+并查集

    题目链接: http://codeforces.com/problemset/problem/650/C C. Table Compression time limit per test4 secon ...

  4. 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 ...

  5. Codeforces Round #345 (Div. 2) E. Table Compression(并查集)

    传送门 首先先从小到大排序,如果没有重复的元素,直接一个一个往上填即可,每一个数就等于当前行和列的最大值 + 1 如果某一行或列上有重复的元素,就用并查集把他们连起来,很(不)显然,处于同一行或列的相 ...

  6. POJ 1456 Supermarket(贪心+并查集)

    题目链接:http://poj.org/problem?id=1456 题目大意:有n件商品,每件商品都有它的价值和截止售卖日期(超过这个日期就不能再卖了).卖一件商品消耗一个单位时间,售卖顺序是可以 ...

  7. Codeforces 437D The Child and Zoo(贪心+并查集)

    题目链接:Codeforces 437D The Child and Zoo 题目大意:小孩子去參观动物园,动物园分非常多个区,每一个区有若干种动物,拥有的动物种数作为该区的权值.然后有m条路,每条路 ...

  8. Codeforces Round #376 (Div. 2) C. Socks---并查集+贪心

    题目链接:http://codeforces.com/problemset/problem/731/C 题意:有n只袜子,每只都有一个颜色,现在他的妈妈要去出差m天,然后让他每天穿第 L 和第 R 只 ...

  9. Codeforces 437D 贪心+并查集

    这个题目让我想起了上次在湘潭赛的那道跪死了的题.也是最值问题,这个也是,有n个动物园 每个都有权值 然后被m条路径相连接,保证图是连通的,然后求所有的p[i][j]之和.i,j为任意两个zoo,pij ...

随机推荐

  1. OC中动态创建可变数组的问题.有一个数组,数组中有13个元素,先将该数组进行分组,每3个元素为一组,分为若干组,最后用一个数组统一管理这些分组.(要动态创建数组).两种方法

    <span style="font-size:24px;">//////第一种方法 // NSMutableArray *arr = [NSMutableArray a ...

  2. Linux 安装、卸载程序

    一, RPM 安装:        rpm -ivh xxx.rpm 重新安装: rpm -ivh -replacepkgs xxx.rpm 卸载:       rpm -e xxx.rpm 二,ta ...

  3. MySQL数据表导出某条记录

    请按照步骤导出,否则可能会报错: ERROR (HY000): The MySQL server is running with the --secure-file-priv option so it ...

  4. Django之邮件发送

    settings.py #settings 添加如下配置进行邮件发送 #邮件服务器 EMAIL_HOST = "smtp.qq.com" #邮件发送的端口 EMAIL_PORT = ...

  5. php解码“&#”编码的中文用函数html_entity_decode()

    遇到类似 ' 这种编码的字,我们可以用html_entity_decode()函数来解码. html_entity_decode() 函数把 HTML 实体转换为字符. 语法 html_entity_ ...

  6. Java 获取本地IP地址

    private static String getIpAddress( ){ String ip = ""; Collection<InetAddress> colIn ...

  7. 数据挖掘、目标检测中的cnn和cn---卷积网络和卷积神经网络

    content 概述 文字识别系统LeNet-5 简化的LeNet-5系统 卷积神经网络的实现问题 深度神经网路已经在语音识别,图像识别等领域取得前所未有的成功.本人在多年之前也曾接触过神经网络.本系 ...

  8. android Bluetooth-蓝牙

    bluetooth 一.开启蓝牙 1.获取BluetoothAdapter BluetoothAdapter.getDefaultAdapter() 2.判断手机设备是否 有蓝牙模块 3.开启蓝牙设备 ...

  9. oc中 中文到拼音的转换

    偶然发现的一个好玩的功能

  10. ios 添加全屏返回手势

    1 建立导航控制器 2.导航控制器添加如下代码 - (void)viewDidLoad { [super viewDidLoad]; id target = self.interactivePopGe ...