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

来源:互联网 发布:电动汽车数据 编辑:程序博客网 时间:2024/05/01 19:27

题意:给你n*m的矩阵,叫你转化成为另外一个矩阵,使得矩阵中的数字之和最小,且同一行,同一列的两个数的关系仍和原来的矩阵相同。

 

思路:因为同一行同一列的两个数仍要满足原来的等价关系,所以就相当于暗含了一个拓扑序,

那么同一行和同一列的数相同的数要怎么办呢?利用一个并查集把他们捆绑起来。(先对原来的序列进行一个排序)

#include <set>#include <map>#include <stack>#include <queue>#include <deque>#include <cmath>#include <vector>#include <string>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define L(i) i<<1#define R(i) i<<1|1#define INF  0x3f3f3f3f#define pi acos(-1.0)#define eps 1e-9#define maxn 1000100#define MOD 1000000007int f[maxn],rx[maxn],ry[maxn];int ans[maxn],pre_rx[maxn],pre_ry[maxn];struct node{    int num,x,y;} mp[maxn];int find(int x){    while(x != f[x])        x = f[x] = f[f[x]];    return f[x];}void merge(int x,int y){    int xx = find(x),yy = find(y);    if(xx != yy)        f[yy] = xx;}bool cmp(node x,node y){    return x.num < y.num;}int main(){    int n,m;    scanf("%d%d",&n,&m);    int cnt = 1;    for(int i = 1; i <= n; i++)        for(int j = 1; j <= m; j++)        {            scanf("%d",&mp[(i-1)*m+j]);            mp[cnt].x = i,mp[cnt++].y = j;            f[(i-1)*m+j] = (i-1)*m + j;        }    sort(mp+1,mp+n*m+1,cmp);    int k;    for(int i = 1; i <= n*m; i = k)    {        for(k = i+1; k <= n*m && mp[k].num == mp[i].num; k++);        for(int j = i; j < k; j++)        {            int x = mp[j].x,y = mp[j].y;            if(!rx[x])                rx[x] = (x-1)*m + y;            else                merge(rx[x],(x-1)*m+y);            if(!ry[y])                ry[y] = (x-1)*m+y;            else                merge(ry[y],(x-1)*m+y);        }        for(int j = i; j < k; j++)        {            int x = mp[j].x,y = mp[j].y,r = find((x-1)*m+y);            ans[r] = max(ans[r],max(pre_rx[x],pre_ry[y])+1);        }        for(int j = i; j < k; j++)        {            int x = mp[j].x,y = mp[j].y,r = find((x-1)*m+y);            ans[(x-1)*m+y] = ans[r];            pre_rx[x] = pre_ry[y] = ans[r];            rx[x] = 0,ry[y] = 0;        }    }    for(int i = 1; i <= n*m; i++)    {        if(i%m == 0)            printf("%d\n",ans[i]);        else            printf("%d ",ans[i]);    }    return 0;}


0 0
原创粉丝点击