codeforces 651E E. Table Compression(贪心+并查集)
题目链接:
4 seconds
256 megabytes
standard input
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.
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 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.
2 2
1 2
3 4
1 2
2 3
4 3
20 10 30
50 40 30
50 60 70
90 80 70
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(贪心+并查集)的更多相关文章
- Codeforces #345div1 C Table Compression (650C) 并查集
题意:给你一个n*m的矩阵,需要在不改变每一行和每一列的大小关系的情况下压缩一个矩阵,压缩后的矩阵所有数的总和尽量的小. 思路:我们有这样的初步设想:对于在一行或一列的数x,y,若x<y,则建立 ...
- Codeforces 651E Table Compression【并查集】
题目链接: http://codeforces.com/problemset/problem/650/C 题意: 给定n*m的矩阵,要求用最小的数表示每个元素,其中各行各列的大小关系保持不变. 分析: ...
- Codeforces Round #345 (Div. 1) C. Table Compression dp+并查集
题目链接: http://codeforces.com/problemset/problem/650/C C. Table Compression time limit per test4 secon ...
- 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 ...
- Codeforces Round #345 (Div. 2) E. Table Compression(并查集)
传送门 首先先从小到大排序,如果没有重复的元素,直接一个一个往上填即可,每一个数就等于当前行和列的最大值 + 1 如果某一行或列上有重复的元素,就用并查集把他们连起来,很(不)显然,处于同一行或列的相 ...
- POJ 1456 Supermarket(贪心+并查集)
题目链接:http://poj.org/problem?id=1456 题目大意:有n件商品,每件商品都有它的价值和截止售卖日期(超过这个日期就不能再卖了).卖一件商品消耗一个单位时间,售卖顺序是可以 ...
- Codeforces 437D The Child and Zoo(贪心+并查集)
题目链接:Codeforces 437D The Child and Zoo 题目大意:小孩子去參观动物园,动物园分非常多个区,每一个区有若干种动物,拥有的动物种数作为该区的权值.然后有m条路,每条路 ...
- Codeforces Round #376 (Div. 2) C. Socks---并查集+贪心
题目链接:http://codeforces.com/problemset/problem/731/C 题意:有n只袜子,每只都有一个颜色,现在他的妈妈要去出差m天,然后让他每天穿第 L 和第 R 只 ...
- Codeforces 437D 贪心+并查集
这个题目让我想起了上次在湘潭赛的那道跪死了的题.也是最值问题,这个也是,有n个动物园 每个都有权值 然后被m条路径相连接,保证图是连通的,然后求所有的p[i][j]之和.i,j为任意两个zoo,pij ...
随机推荐
- fastJson 转换日期格式
第一种方法: JSON.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd"; String str = JSON.toJSONString(user,Seria ...
- linux 内核(系统)、函数的理解、宏的程序调试
1.操作系统 1.1.Linux 内核(系统)的组成的部分: 内核主要有:进程调度.内存管理.虚拟文件系统.网络接口和进程通信五个部分组成. (1)进程调度 进程调度是CPU对多个进程对CPU访问的调 ...
- 【Sprint3冲刺之前】TD学生助手——alpha版发布
TD学生助手——alpha版发布 1.设想和目标 1.我们的软件要解决的问题 TD学生助手的主要核心思想就是帮助学生安排他们忙碌的学校生活.主要是通过以下几个方面 1.通过学生的需要进行分类(考试, ...
- D类功放基础简介
DAC和D类PA的开关时序是先开dac再开D类pa,先关D类pa再关dac
- 扩展MongoDB C# Driver的QueryBuilder
扩展MongoDB C# Driver的QueryBuilder 因为不想直接hardcode "ClassA.MemberA.MemberB" 这种字符串 .写了下面几个类,用于 ...
- Ubuntu Server 安装 NodeJS
准备命令: $ sudo apt-get install python $ sudo apt-get install build-essential $ sudo apt-get install gc ...
- Linux XMind
XMind这个软件好像不错的样子,至少在Windows/Linux/Mac下都可以工作,作为FreeMind的替代品应该是没什么问题(还有一个vym貌似也可以,可能没有XMind好,毕竟XMind有公 ...
- Paxos算法学习
早在1990年,Leslie Lamport(即 LaTeX 中的"La",微软研究院科学家,获得2013年图灵奖)向ACM Transactions on Computer Sy ...
- Spark源码分析之八:Task运行(二)
在<Spark源码分析之七:Task运行(一)>一文中,我们详细叙述了Task运行的整体流程,最终Task被传输到Executor上,启动一个对应的TaskRunner线程,并且在线程池中 ...
- JAVA进阶-多线程(2)
堵塞队列: 1)BlockingQueue该接口提供了: add()/remove() 假设当队列没有数据,从队列中取数据;或者队列中数据已满, 向队列中加入数据;则会抛出异常. put()/take ...