Codeforces Round #764 (Div. 3) G題
阿新 • • 發佈:2022-01-12
本人第一篇題解。
這一題對我來說是有點難的。本題的本質就是貪心,這場比賽都是貪心。
我們將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; }