Question Portal
Portal
Theme
Each vertex has a vertex weight $ a_ I $. The Edge Weight of the edge of $ U $ and the vertex $ V $ is $ a_u \ and \ a_v $. Ask the maximum spanning tree.
We consider each edge weight from the largest to the smallest. If the vertex weights of Two unconnected points simultaneously contain this edge weight as a subset, it is obvious that such edges are used to connect these points to the optimum.
Therefore, we use and query sets to retrieve a token for each edge weight that has been considered.
Each time a new edge weight is enumerated, some existing connected blocks are merged.
Code
1 /** 2 * uoj 3 * Problem#176 4 * Accepted 5 * Time: 1128ms 6 * Memory: 3276k 7 */ 8 #include <iostream> 9 #include <cstdlib>10 #include <cstdio>11 #ifndef WIN3212 #define Auto "%lld"13 #else14 #define Auto "%I64d"15 #endif16 using namespace std;17 typedef bool boolean;18 19 #define ll long long20 21 template <typename T>22 void pfill(T* pst, const T* ped, T val) {23 for ( ; pst != ped; *(pst++) = val);24 }25 26 int n, m;27 int S;28 int *f, *ar;29 ll res = 0;30 31 int find(int x) {32 return (f[x] == x) ? (x) : (f[x] = find(f[x]));33 }34 35 inline void init() {36 scanf("%d%d", &n, &m);37 S = 1 << m;38 f = new int[S];39 ar = new int[S];40 pfill(ar, ar + S, 0);41 for (int i = 1, x; i <= n; i++) {42 scanf("%d", &x);43 if (!ar[x])44 f[x] = x, ar[x] = x;45 else46 res += x;47 }48 }49 50 inline void solve() {51 for (int s = S - 1, x, y; s; s--) {52 for (int i = 0; !ar[s] && i < m; ar[s] |= ar[s | (1 << (i++))]);53 if (!(x = ar[s]))54 continue;55 for (int i = 0; i < m; i++)56 if (ar[s | (1 << i)]) {57 y = find(ar[s | (1 << i)]);58 if (y ^ find(x)) {59 f[y] = find(x), ar[s] = find(x);60 res += s;61 }62 }63 }64 printf(Auto, res);65 }66 67 int main() {68 init();69 solve();70 return 0;71 }
Uoj 176 New Year's boom-greedy-Query