标签:return tree LL 1624G Tree CF fa spanning find
题目链接:
https://codeforces.com/problemset/problem/1624/G
题目大意:
一棵 \(spanning tree\) 的 \(ority\) 就是它所有边权的位或值,现在给出一个图,求出里面 \(spanning tree\) 的 \(ority\) 的最小值,\(spanning tree\) 就是一个无环的连通子图。
思路:
刚开始看到题目的时候,第一时间想到的是最小生成树,每次添加一条最小的边到已知集合中,但是这个最小不好判断。于是反过来考虑,从“避圈法”改为“破圈法”。
因为要求最小的位或值,所以我们可以枚举二进制的每一位,去除掉该位为 1 的边,剩下的如果是连通图,那么该位就可以去掉,通过这种方式去去掉边。
代码:
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 2e5 + 10;
LL T = 1, n, m, fa[N];
struct node{
LL u, v, w;
}e[N];
LL find(LL x){
if (fa[x] == x) return x;
return fa[x] = find(fa[x]);
}
void join(LL a, LL b){
fa[find(b)] = find(a);
}
bool judge(LL x){
for (int i = 1; i <= n; i++)
fa[i] = i;
for (int i = 1; i <= m; i++){
if (e[i].w & x) continue;
join(e[i].u, e[i].v);
}
for (int i = 2; i <= n; i++)
if (find(fa[i]) != find(fa[i - 1]))
return false;
return true;
}
void solve(){
scanf("%lld%lld", &n, &m);
for (int i = 1; i <= m; i++)
scanf("%lld%lld%lld", &e[i].u, &e[i].v, &e[i].w);
LL res = 0;
for (int bit = 29; bit >= 0; bit--){
LL cur = res + (1LL << bit);
if (judge(cur))
res += (1LL << bit);
}
cout << (1LL << 30) - 1 - res << "\n";
}
int main(){
cin >> T;
while (T--)
solve();
return 0;
}
标签:return,tree,LL,1624G,Tree,CF,fa,spanning,find 来源: https://www.cnblogs.com/Hamine/p/15858615.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。