A. Rikka with Minimum Spanning Trees
题意:
给出一个图,求最小生成树的个数和权值
思路:
因为数据随机,只有一个MST
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define ull unsigned long long 5 ull k1, k2; 6 const ull MOD = (ull)1e9 + 7; 7 int t, n, m; 8 9 ull f() 10 { 11 ull k3 = k1, k4 = k2; 12 k1 = k4; 13 k3 ^= k3 << 23; 14 k2 = k3 ^ k4 ^ (k3 >> 17) ^ (k4 >> 26); 15 return k2 + k4; 16 } 17 18 struct Edge 19 { 20 int u, v; ull w; 21 Edge() {} 22 Edge(int u, int v, ull w) : u(u), v(v), w(w) {} 23 bool operator < (const Edge &other) const { return w < other.w; } 24 }edge[100010]; 25 26 int fa[100010]; 27 int find(int x) { return fa[x] == 0 ? x : fa[x] = find(fa[x]); } 28 29 void Kruskal() 30 { 31 memset(fa, 0, sizeof fa); 32 sort(edge + 1, edge + 1 + m); 33 int cnt = 1; 34 ull res = 0; 35 for (int i = 1; i <= m; ++i) 36 { 37 int u = edge[i].u, v = edge[i].v; ull w = edge[i].w; 38 // cout << i << " " << w << endl; 39 int fu = find(u), fv = find(v); 40 if (fu == fv) continue; 41 ++cnt; 42 res = (res + w) % MOD; 43 fa[fu] = fv; 44 if (cnt == n) break; 45 } 46 if (cnt != n) res = 0; 47 printf("%llu\n", res); 48 } 49 50 int main() 51 { 52 scanf("%d", &t); 53 while (t--) 54 { 55 scanf("%d%d%llu%llu", &n, &m, &k1, &k2); 56 for (int i = 1; i <= m; ++i) 57 { 58 edge[i].u = f() % n + 1; 59 edge[i].v = f() % n + 1; 60 edge[i].w = f(); 61 // cout << edge[i].u << " " << edge[i].v << " " << edge[i].w << endl; 62 } 63 Kruskal(); 64 } 65 return 0; 66 }