uva live 7638 Number of Connected Components (并查集)
题意:
每两个点如果他们的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("\n"); 86 } 87 return 0; 88 }