本人第一篇题解。
这一题对我来说是有点难的。本题的本质就是贪心,这场比赛都是贪心。
我们将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;
}