Minimum Or Spanning Tree - 题目 - Daimayuan Online Judge
题意:
思路:
求最小的生成树,考虑按位贪心,即从高位往低位贪心
对于这类按位贪心问题,一般考虑从高位往低位贪,然后check这位能不能是0/1
对于这道题,因为是最小,所以优先考虑这位能不能贪成0,然后去check
怎么check呢,check函数里,问题就转化为:选一些边,使得不成环且或起来这位是0
Code:
void slove() {
cin >> n >> m;
vector<edge>e;
for (int i = 1; i <= m; i++) {
cin >> u >> v >> w;
e.push_back({ u,v,w });
}
int ans = 0;
for (int i = 30; i >= 0; i--) {
vector<edge>ne;//新的边的集合
UF uf = UF(n);
for (auto ed : e) {
u = ed.u, v = ed.v, w = ed.w;
if (((w >> i) & 1) == 0){
ne.push_back(ed);
uf.Union(u, v);//并查集连接u v
}
}
if (uf.count == 1) {
e = ne;//如果仅靠0的边就能联通,删除1的边
ans += (0 << i);//为了对称
}
else {
//如果不能联通,答案的这一位只能是1了
ans += (1 << i);
}
}
cout << ans << endl;
}