HDU 5627 Clarke and MST(贪心、连通性)
2016-02-13 22:38
232 查看
题意:
N,M≤3×105的无向图,求权值位与(&)运算的最大生成树
分析:
首先与运算的性质就是参与运算的该位全是1结果才是1
先把边按照该位是不是1分类,对于生成怎么样的生成树我们不关心,只要抓住如果这些边能让这个图连通,那么一定能生成树
所以从高位到低位枚举这些边是不是连通即可
时间复杂度为O(30mα(n))
代码:
N,M≤3×105的无向图,求权值位与(&)运算的最大生成树
分析:
首先与运算的性质就是参与运算的该位全是1结果才是1
先把边按照该位是不是1分类,对于生成怎么样的生成树我们不关心,只要抓住如果这些边能让这个图连通,那么一定能生成树
所以从高位到低位枚举这些边是不是连通即可
时间复杂度为O(30mα(n))
代码:
// // Created by TaoSama on 2016-02-13 // Copyright (c) 2016 TaoSama. All rights reserved. // #pragma comment(linker, "/STACK:1024000000,1024000000") #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; #define pr(x) cout << #x << " = " << x << " " #define prln(x) cout << #x << " = " << x << endl const int N = 3e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7; int n, m; struct Edge { int u, v, c; }; vector<Edge> G[30]; struct DSU { int p ; void init() { for(int i = 1; i <= n; ++i) p[i] = i; } int find(int x) { return p[x] = p[x] == x ? x : find(p[x]); } void unite(int x, int y) { x = find(x), y = find(y); if(x == y) return; p[x] = y; } int count() { int cc = 0; for(int i = 1; i <= n; ++i) cc += p[i] == i; return cc; } } dsu; bool isConnected(int x, int p) { dsu.init(); for(Edge& e : G[x]) { if(e.c >> p & 1) { dsu.unite(e.u, e.v); } } return dsu.count() == 1; } int solve(int x) { int ret = 1 << x; for(int i = x - 1; ~i; --i) { if(isConnected(x, i)) ret |= 1 << i; } return ret; } int main() { #ifdef LOCAL freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin); // freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); int t; scanf("%d", &t); while(t--) { scanf("%d%d", &n, &m); for(int i = 0; i < 30; ++i) G[i].clear(); for(int i = 1; i <= m; ++i) { int u, v, c; scanf("%d%d%d", &u, &v, &c); for(int j = 0; j < 30; ++j) if(c >> j & 1) G[j].push_back((Edge) {u, v, c}); } int ans = 0; for(int i = 29; ~i; --i) { if(isConnected(i, i)) { ans = solve(i); break; } } printf("%d\n", ans); } return 0; }
相关文章推荐
- 1.一些 贪心算法 的简单思维题:
- 贪心算法——字典序最小问题
- 贪心算法——区间调度问题
- Jump Game I,II 贪心
- Wildcard Matching
- 贪心法实现无向图的划分 代码
- 贪心题目循环和控制台折行
- HDOJ 1009
- 【解题报告】【USACO】酸奶工厂
- 【解题报告】【】交谊舞
- POJ 1328
- Best Cow Line
- HDU 1009 Fatmouse's Trade
- POJ2377 Bad Cowtractors
- 贪心 hdu 1003
- 最大容器
- 满足和为定值的两个数或多个数
- Codeforces Round #300
- HUD1052 __ P2 1002 __ Tian Ji -- The Horse Racing
- 2015年国家集训队测试 BZOJ3816矩阵变幻