CF1634E Fair Share

Posted solemntee

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;


以上是关于CF1634E Fair Share的主要内容,如果未能解决你的问题,请参考以下文章

CF 987 D. Fair

uvalive 3231 Fair Share 公平分配问题 二分+最大流 右边最多流量的结点流量尽量少。

CF 1084 D. The Fair Nut and the Best Path

E. Fair Share

E. Fair Share

E. Fair Share