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 }
View Code

相关文章: