0
点赞
收藏
分享

微信扫一扫

CF1634E Fair Share

龙毓七七 2022-03-13 阅读 60
图论算法

题意:

m m m 个数组,每个数组长度为 n i n_i ni
要在每组间恰好划分一半进可重集 L L L,剩下的进 R R R
要求判断能否找出一组划分方式,使 L L L R R R 相同。

思路:

题目要求最终的 L L L R R R 相同,考虑转化成数据中的一些互相对立的关系,从而想到建图后黑白染色。

容易发现,只有所有数都出现了偶数次才有解,于是可以先把 No 给判掉。

考虑按如下方式建图:
定义“一组”表示一个数组中相邻两元素。

  1. 在两个相邻的,值相同的数之间连边。
  2. 在每一组之间连边。

可知若两数之间有边,则它们所对应的组也一定联通。

所以在最终的图中,不会出现长度为奇数的环,即它是一个二分图。

这样再黑白染色一下就可以了。

代码:

#include<bits/stdc++.h>
using namespace std;
#define mk(a,b) make_pair(a,b)
const int maxn=400005;
int head[maxn],mx,tim,edgenum,m,color[maxn],n[maxn],b[maxn],d[maxn],cnt[maxn];
map<pair<int,int>,int>mat;
vector<pair<int,int> >c[maxn];
vector<int>a[maxn];
struct node{
	int to,nxt;
}edge[maxn];
void add(int u,int v){
	edgenum++;
	edge[edgenum].to=v;
	edge[edgenum].nxt=head[u];
	head[u]=edgenum;
}
void dfs(int u,int col){
	color[u]=col;
	for(int e=head[u];e;e=edge[e].nxt){
		int v=edge[e].to;
		if(color[v]) continue;
		dfs(v,(col==1?2:1));
	}
}
int main(){
	scanf("%d",&m);
	int tot=0;
	for(int i=1;i<=m;i++){
		scanf("%d",&n[i]);
		for(int j=1;j<=n[i];j++)
			scanf("%d",&b[++tot]),a[i].push_back(b[tot]);
	}
	sort(b+1,b+tot+1);
	tot=unique(b+1,b+tot+1)-b-1;
	for(int i=1;i<=m;i++)
		for(int j=0;j<a[i].size();j++)
			a[i][j]=lower_bound(b+1,b+tot+1,a[i][j])-b;
	tot=0;
	for(int i=1;i<=m;i++)
		for(int j=1;j<=n[i];j++)
			mat[mk(i,j)]=++tim;
	for(int i=1;i<=m;i++){
		for(int j=1;j<=n[i];j++){
			if(j%2==0){
				add(mat[mk(i,j-1)],mat[mk(i,j)]);
				add(mat[mk(i,j)],mat[mk(i,j-1)]);
			}
			cnt[a[i][j-1]]++;
			c[a[i][j-1]].push_back(mk(i,j));
			d[++mx]=a[i][j-1];
		}
	}
	for(int i=1;i<=mx;i++) 
		if(cnt[d[i]]%2!=0){
			printf("NO");
			return 0;
		}
	for(int i=1;i<=mx;i++)
		for(int j=0;j<c[i].size();j++){
			if(j%2==1){
				add(mat[c[i][j-1]],mat[c[i][j]]);
				add(mat[c[i][j]],mat[c[i][j-1]]);
			}
		}
	for(int i=1;i<=tim;i++)
		if(!color[i]) dfs(i,1);
	printf("YES\n");
	for(int i=1;i<=m;i++){
		for(int j=1;j<=n[i];j++){
			int id=mat[mk(i,j)];
			if(color[id]==1) printf("L");
			else printf("R");
		}
		printf("\n");
	}
	return 0;
}
举报

相关推荐

0 条评论