Codeforces Round #764 (Div. 3) G题

本人第一篇题解。
这一题对我来说是有点难的。本题的本质就是贪心,这场比赛都是贪心。
我们将ans置为最大值(1 << 30) - 1, 然后我们一位一位到的取check(), 看一下这一位是否能置为0,如果可以话,就将这一位置为0,最后输出ans;

#include <iostream>
#include <cstring>
#include <algorithm>
#include <tuple>
#include <vector>
#include <numeric>

using namespace std;

typedef tuple<int, int, int> tp;

const int N = 2e5 + 10;

struct UniFind {
	int n;
	vector<int> f, sizeN;

	UniFind(int _n = 0)
	{
		f.resize((n = _n) + 10);
		sizeN.resize(n + 10, 1);
	}

	int find(int x)
	{
		if(x != f[x]) f[x] = find(f[x]);
		return f[x];
	}

	int size(int x)
	{
		return sizeN[find(x)];
	}

	void uni(int a, int b)
	{
		a = find(a), b = find(b);
		if(a != b)
		{
			f[a] = b;
			sizeN[b] += sizeN[a];
		}
	}

	void clear()
	{
		sizeN.assign(n + 10, 1);
		iota(f.begin(), f.end(), 0);
	}
} un;

int n, m;
int u[N], v[N], w[N];

bool check(int x)
{
	un.clear();
	for(int i = 1; i <= m; i ++)
		if((w[i] & x) == w[i])
			un.uni(u[i], v[i]);
	return un.size(1) == n;
}

void work()
{
	cin >> n >> m;

	un = UniFind(n);
	for(int i = 1; i <= m; i ++)
		cin >> u[i] >> v[i] >> w[i];

	int ans = (1 << 30) - 1;
	for(int i = 29; i >= 0; i --)
		if(check(ans^1 << i))
			ans^= 1 << i;

	cout << ans << endl;
}

int main()
{
	int t;
	cin >> t;
	while(t --)
	{
		work();
	}

	return 0;
}
上一篇:Codeforces Round #765 (Div. 2) A~C 题解(原来如此简单,超级详细入门必备)


下一篇:adb 获取Android手机信息命令(2)