CF1634E Fair Share

在这里插入图片描述
题意:有 m m m个数组,每个数组数字数量都是偶数。把每个数组对半分给集合 A 、 B A、B AB使得最终得到的可重集相同判断是否合法并且给出方案。
首先赛场上大概就只想到欧拉回路,但是因为没有拆点建图,只能做不可重集的情况,后来也就无奈下播。
做法是建立一张二部图,左部 m m m个点表示每个数组,右部 c n t cnt cnt(数字种类数)个点。
左部向右部数字 i i i的有向边表示 i i i分给 A A A集合,反之表示分给 B B B集合。容易知道原问题等价于二分图上搜欧拉回路。
然后因为也不需要输出路径,就用类似黑白染边,然后不断搜环就可。
然后搜出个环肯定不影响补图的欧拉回路性质嘛,欧拉图肯定能搜个环也是显然的,就证明完毕了。
顺便请大家欣赏一下新学的 l a m b d a lambda lambda函数

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
	int m;
	scanf("%d",&m);
	vector<vector<int>>a(m+1),ans(m+1);
	map<int,int>mp,cnt;
	int asdf=0;
	for(int i=1;i<=m;i++)
	{
		int n;
		scanf("%d",&n);

		a[i].resize(n+1);
		ans[i].resize(n+1,-1);
		for(int j=1;j<=n;j++)
		{
			scanf("%d",&a[i][j]);
			if(mp[a[i][j]]==0)mp[a[i][j]]=++asdf;
			cnt[mp[a[i][j]]]++;
		}
	}
	for(int i=1;i<=asdf;i++)if(cnt[i]%2==1)
	{
		printf("NO");
		return 0;
	}
	vector<vector<pair<int,int>>>gra(4e5+5);
	vector<int>cur(4e5+5);
	const int MX=2e5;
	for(int i=1;i<=m;i++)
	{
		for(int j=1;j<a[i].size();j++)
		{
			gra[i].push_back({mp[a[i][j]]+MX,j});
			gra[MX+mp[a[i][j]]].push_back({i,j});
			cur[i]++;
			cur[MX+mp[a[i][j]]]++;
		}
	}
	function<void(int,int)>dfs=[&](int now,int flag)
	{
		int u=now;
		while(cur[u])
		{
			cur[u]--;
			auto [to,pos]=gra[u][cur[u]];
			while(ans[min(u,to)][pos]<0)
			{
				ans[min(u,to)][pos]=flag;
				dfs(to,1-flag);
			}
		}
	};
	for(int i=1;i<=m;i++)dfs(i,0);
	printf("YES\n");
	for(int i=1;i<=m;i++)
	{
		for(int j=1;j<ans[i].size();j++)
		{
			if(ans[i][j]==0)printf("L");
			else printf("R");
		}
		printf("\n");
	}

    return  0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值