uva live 7638 Number of Connected Components (并查集)

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5660

题意:

  每两个点如果他们的gcd大于1的话就可以连一条边,问在这些数里面有多少个联通块。

题解:

  我们可以用筛法倍数。然后用并查集将他们连通起来,2 3 6 本来2 和3的gcd 为1,但是他们可以通过6使得连通。

  还有就是要注意 15 25 35 这个数据。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <string>
 5 #include <algorithm>
 6 #include <cmath>
 7 #include <vector>
 8 #include <queue>
 9 #include <map>
10 #include <stack>
11 #include <set>
12 using namespace std;
13 typedef long long LL;
14 typedef unsigned long long uLL;
15 #define ms(a, b) memset(a, b, sizeof(a))
16 #define pb push_back
17 #define mp make_pair
18 #define eps 0.0000000001
19 #define IOS ios::sync_with_stdio(0);cin.tie(0);
20 const LL INF = 0x3f3f3f3f3f3f3f3f;
21 const int inf = 0x3f3f3f3f;
22 const int mod = 1e9+7;
23 const int maxn = 1000000+10;
24 int num[maxn];
25 int F[maxn];
26 vector <int> now;
27 int findfa(int x)
28 {
29     if(F[x]==x){
30         return x;
31     }
32     else return F[x] = findfa(F[x]);
33 }
34 int join(int x, int y)
35 {
36     int f1 = findfa(x);
37     int f2 = findfa(y);
38     if(f1!=f2){
39         if(f1>f2) swap(f1, f2);
40         F[f2] = f1;
41     }
42 }
43 void solve()
44 {
45     ms(num, 0);
46     for(int i = 2;i<maxn;i++)   F[i] = i;
47     int n, x, Max = 0;
48     scanf("%d", &n);
49     for(int i = 0;i<n;i++){
50         scanf("%d", &x);
51         num[x]++;
52         Max = max(Max, x);
53     }
54     for(int i = 2;i<=Max;i++){
55         now.clear();
56         for(int j = 1;i*j<=Max;j++){
57             if(num[i*j])
58                 now.pb(i*j);
59         }
60         if(now.size()>=2){
61             for(int k = 1;k<now.size();k++)
62                 join(now[0], now[k]);
63         }
64     }
65     int ans = 0;
66     for(int i = 2;i<=maxn;i++){
67         if(num[i]&&i==F[i]){
68             ans++;
69         }
70     }
71     ans += num[1];
72     printf("%d", ans);
73 }
74 int main() {
75 #ifdef LOCAL
76     freopen("input.txt", "r", stdin);
77 //        freopen("output.txt", "w", stdout);
78 #endif
79 //    IOS
80     int t;scanf("%d", &t);
81     int cnt = 1;
82     while(t--){
83         printf("Case %d: ", cnt++);
84         solve();
85         printf("
");
86     }
87     return 0;
88 }
View Code
原文地址:https://www.cnblogs.com/denghaiquan/p/7287020.html