B. Sets and Union

topic:

Example:

enter
4
3
3 1 2 3
2 4 5
2 3 4
4
4 1 2 3 4
3 2 5 6
3 3 5 6
3 4 5 6
5
1 1
3 3 6 10
1 9
2 1 3
3 5 8 9
1
2 4 28

output
4
5
6
0

Idea:

        The meaning of the question here is to merge as many sets as possible to maximize the set size, but it cannot be equal to the merge of all sets.

        Since the range given in the question is small, we can violently enumerate. Secondly, there is also an element of greed. Here we change our thinking. We use the total set and based on a certain element in the total set, the enumeration does not exist. The combination of the set of elements is not equal to the combination of all sets. Taking the maximum number of sets after the merge is the answer.

The code is explained in detail below:

#include <iostream>
#include <vector>
#include <unordered_set>
#include <unordered_map>
#define endl '\n'
#define YES puts("YES")
#define NO puts("NO")
#define umap unordered_map
#define uset unordered_set
#pragma GCC optimize(3,"Ofast","inline")
#define ___G std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
using namespace std;
const int N = 2e6 + 10;

inline void solve()
{	
	int t,ans = 0;
	
	umap<int,vector<int>>v;	// 记录每个集合
	
	uset<int>sum;	// 统计总集合
	
	cin >> t;	// t 为集合个数
	for(int i = 1;i <= t;++i)
	{
		int n;	// 集合大小
		cin >> n; 
		for(int j = 1;j <= n;++j)
		{
			int x;	// 集合元素
			cin >> x;
			
			// 记录该集合
			v[i].emplace_back(x);
			
			// 统计总集合元素
			sum.insert(x);
		}
	}
	
	// 开始 贪心删除
	for(auto now : sum)
	{	
		// 选择删除后的合并集合
		uset<int>tem;
		
		for(int i = 1;i <= t;++i)
		{
			// st 标记是否删除该集合
			bool st = false;
			
			// 遍历该集合
			for(auto j : v[i])
			{
				// 如果 sum 中的某个元素存在该集合
				// 那么我们选着的是删除这个集合
				// 所以无需添加
				if(now == j)
				{
					st = true;
					break;
				}
			}
			
			// 如果该集合不用删除,那么我们就添加该集合的元素
			if(!st)
			{
				for(auto j : v[i]) tem.insert(j);
			}	
		}
		// 判断选择删除这个元素后的,所有集合大小
		// 选择答案 合并集合个数最大,但不等于 sum 集合
		ans = max(ans,(int)tem.size());
	}
	
	cout << ans << endl;
}

int main()
{
//	freopen("a.txt", "r", stdin);
	___G;
	int _t = 1;
	cin >> _t;
	while (_t--)
	{
		solve();
	}
	return 0;
}

Last commit:

Guess you like

Origin blog.csdn.net/hacker_51/article/details/133358374