1. 程式人生 > >【並查集】【枚舉倍數】UVALive - 7638 - Number of Connected Components

【並查集】【枚舉倍數】UVALive - 7638 - Number of Connected Components

pre val 輸出 live ring algorithm ostream %d using

題意:n個點,每個點有一個點權。兩個點之間有邊相連的充要條件是它們的點權不互素,問你這張圖的連通塊數。

從小到大枚舉每個素數,然後枚舉每個素數的倍數,只要這個素數的某個倍數存在,就用並查集在這些倍數之間都連上邊。然後輸出最後的集合數量即可。

註意,點權為1的點都會自成一個連通塊。

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int T,a[1000006],fa[1000006],f[1000006],p[1000006],ans,n,t,notPrime[1000006],prime[1000006],num;
int get(int x){return fa[x]==x?x:fa[x]=get(fa[x]);}
void un(int x,int y)
{
    int Y=get(y);int X=get(x);
    if(X!=Y)
    {
        fa[X]=Y;
    }
}
char ch;
int temp;
int read()
{
    while(ch=getchar(),ch<‘0‘||ch>‘9‘);
    temp=ch-‘0‘;
    while(ch=getchar(),ch<=‘9‘&&ch>=‘0‘)
        temp=temp*10+ch-‘0‘;
    return temp;
}
int main()
{
 //   freopen("1.in","r",stdin);
  //  freopen("1.out","w",stdout);
    for(int i=2;i<=1000000;++i)
    {
        if(!notPrime[i])
        {
            prime[++num]=i;
        }
        for(int j=1;j<=num&&prime[j]*i<=1000000;++j)
        {
            notPrime[i*prime[j]]=1;
            if(i%prime[j]==0) break;
        }
    }
    scanf("%d",&T);
    int maxi=1000000;
    for(int tt=1;tt<=T;++tt)
    {
        n=read();
        for(int i=1;i<=maxi;++i)
        {
            fa[i]=i;
            f[i]=0;
            a[i]=0;
        }
        maxi=0;
        ans=0;
        for(int i=1;i<=n;++i)
        {
            t=read();
            if(t==1) ans++;
            maxi=max(maxi,t);
            a[t]=1;
        }
        for(int i=1;i<=num;++i)
        {
            int now=prime[i];
            int tail=0;
            for(int j=1;now*j<=maxi;++j)
            {
                if(a[now*j])
                p[++tail]=now*j;
            }
            for(int j=1;j<tail;++j)
            {
                un(p[j],p[j+1]);
            }
        }
        for(int i=2;i<=maxi;++i)
        if(a[i])
        {
            if(!f[get(i)]) ans++;
            f[get(i)]=1;
        }
        printf("Case %d: %d\n",tt,ans);
    }

}

【並查集】【枚舉倍數】UVALive - 7638 - Number of Connected Components