版权声明:本文为博主瞎写的,请随便转载 https://blog.csdn.net/sdut_jk17_zhangming/article/details/85062442
题目 https://cn.vjudge.net/problem/UVALive-7638
题意
给你N个数 如果两个数的GCD不为1 则有一条线相连 问有多少独立的分块
思路
并查集
#include <bits/stdc++.h>
using namespace std;
int a[100500];
int arr[1000500];
int h[100];
bool vis[1005000];
int pos[1005000];
int f(int x)
{
return arr[x] == x? x : arr[x] = f(arr[x]);
}
int main()
{
int t,n;
int w=0;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
int ant=0;
memset(vis,false,sizeof(vis));
for(int i=0; i<=1000006; i++)arr[i]=i;
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
vis[a[i]]=true;
}
sort(a+1,a+1+n);
for(int i=1;i<=n;i++)
{
if(a[i] == 1) ant++;
else break;
}
n = unique(a+1,a+1+n) - a;
for(int i=1; i<=n; i++)
{
int x=a[i];
int ans=0;
for(int j=2; j*j<=x; j++)
{
if(x%j==0)
{
while(x%j==0)
{
x=x/j;
}
h[ans++]=j;
}
}
if(x!=1)h[ans++]=x;
for(int j=0; j<ans; j++)
{
int p=h[j];
if(f(a[i])!=f(p))
{
arr[f(a[i])]=f(p);
}
}
}
int num=0;
memset(pos,0,sizeof(pos));
for(int i=2; i<=1000000; i++)
{
if(vis[i])
{
int p=f(i);
if(!pos[p])
{
num++;
pos[p]=1;
}
}
}
//cout<<num<<" "<<ant<<endl;
printf("Case %d: %d\n",++w,num+ant);
}
return 0;
}