题解 CF650C 【Table Compression】

题解 - C F 650 C \mathrm{CF650C}

题目意思

S o l \mathrm{Sol}

  • 并查集+拓扑

  • 首先我们考虑关系图很能想到拓扑排序对吧!然后我们可以把一行中权值相同的点合成一个联通块。

  • 于是就重新建图(及不同联通块之间连边)

  • 还有我们不好找起点于是就随意定个虚点以其为起点跑有向图上的最长路即可。

  • 时间复杂度: O ( n × m log ( n × m ) ) O(n\times m \log (n\times m))

C o d e \mathrm{Code}

#include <bits/stdc++.h>
#define For(i,a,b) for ( int i=(a);i<=(b);i++ )
#define Dow(i,b,a) for ( int i=(b);i>=(a);i-- )
#define GO(i,x) for ( int i=head[x];i;i=e[i].nex )
#define mem(x,s) memset(x,s,sizeof(x))
#define cpy(x,s) memcpy(x,s,sizeof(x))
#define YES return puts("YES"),0
#define NO return puts("NO"),0
#define GG return puts("-1"),0
#define pb push_back
#define lowbit(x) x&(-x)
using namespace std;

inline int read()
{
	int sum=0,ff=1; char ch=getchar();
	while(!isdigit(ch))
	{
		if(ch=='-') ff=-1;
		ch=getchar();
	}
	while(isdigit(ch))
		sum=sum*10+(ch^48),ch=getchar();
	return sum*ff;
}

const int mod=1e9+7;
const int mo=998244353;
const int N=1e6+5;

int n,m,fa[N],in[N],d[N],id;

inline int ID(int x,int y) {return (x-1)*m+y;}
inline int min(int x,int y) {if(x<y) return x; return y;}
inline int max(int x,int y) {if(x>y) return x; return y;}

inline int find(int x)
{
	if(x==fa[x]) return x;
	return fa[x]=find(fa[x]);
}

struct Node
{
	int x,id;
	inline bool friend operator < (const Node&a,const Node&b)
	{
		return a.x<b.x;
	}
};
vector<Node> a[N],b[N];
vector<int> G[N];

int main()
{
	n=read();
	m=read();
	For(i,1,n) For(j,1,m) 
	{
		int x=read();
		++id;fa[id]=id;
		a[i].pb((Node){x,ID(i,j)});
		b[j].pb((Node){x,ID(i,j)});
	}
	For(i,1,n) 
	{
		sort(a[i].begin(),a[i].end());
		For(j,0,m-2) 
		{
			Node A=a[i][j],B=a[i][j+1];
			if(A.x==B.x) fa[find(A.id)]=find(B.id);
		}
	}
	For(i,1,m) 
	{
		sort(b[i].begin(),b[i].end());
		For(j,0,n-2)
		{
			Node A=b[i][j],B=b[i][j+1];
			if(A.x==B.x) fa[find(A.id)]=find(B.id);
		}
	}
	For(i,1,n*m) if(find(i)==i) G[0].pb(i),in[i]++;
	For(i,1,n) For(j,0,m-2)
	{
		Node A=a[i][j],B=a[i][j+1];
		int x=find(A.id),y=find(B.id);
		if(x!=y) G[x].pb(y),in[y]++;
	}
	For(i,1,m) For(j,0,n-2)
	{
		Node A=b[i][j],B=b[i][j+1];
		int x=find(A.id),y=find(B.id);
		if(x!=y) G[x].pb(y),in[y]++;
	}
	queue<int> q;
	q.push(0);
	while(q.size())
	{
		int u=q.front();q.pop();
		For(i,0,(int)G[u].size()-1) 
		{
			int v=G[u][i];
			d[v]=max(d[u]+1,d[v]);
			if(!(--in[v])) q.push(v);
		}
	}
	For(i,1,n) 
	{
		For(j,1,m) printf("%d ",d[find(ID(i,j))]);
		puts("");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/wangyiyang2/article/details/107108820