(组队赛E/F Number of Connected Components )UVALive

来源:互联网 发布:我的世界清空玩家数据 编辑:程序博客网 时间:2024/06/05 19:14

这个题,,,!!!!!大坑比!!!我从比赛开始一直在看题,直到比赛结束也不知道这个题的意思是嘛,很气啊,非常气!!

最后知道了,就是在所有给你的数据当中,只要是存在倍数关系的就连为一体,即使是2和3应为如果有6的话,2与6有关系,3与6有关系那么2与3 也是有关系的那就为一组,

最后问你能够分成几组

。。。真无奈,这个题用一个并查集来联合所有的数据,然后再提前打好表来提前处理庞大的数据防止超时,将每个数的因子存到一个集合中去,当这个数出现在数据中时就将它所有数据处理好,并集,

但注意我一开始是在输入数据前就将树生成,在每次测试中将所有的数的因子全部并集,但是这样是错的,因为如果你提前就将数所有的集合并起来之后,如果输入2和3,倘若数据中没有6(或者其他2和3的公约数)的话,2和3应该是属于两个不同的集合,而你却早将2,3化为一组,这样就错了,所以应该是在每组测试用例输入时建一个新树


还有一个自己傻逼的错误,runtime error,数组开小了,数据数N最多是10五次方,但是s的下标是Xi,最大是10的6次方;还有个更傻的错误,find()函数return忘了写;

额,,还有void函数写成了int


#include <iostream>#include<vector>#include<cstring>#include<cstdio>using namespace std;const int maxn=1000000+5;vector<int> s[maxn];int flag[maxn];int pra[maxn];int a[maxn];void inint(int n){    for(int i=0;i<n;i++)        pra[i]=i;}int find(int x){    if(x==pra[x])        return x;    else      return  pra[x]=find(pra[x]);}void unit(int x,int y){    int a=find(x);    int b=find(y);    if(a!=b)    {   if(a>b)       pra[b]=a;       else        pra[a]=b;    }}int main(){    for(int i=2;i<maxn;i++)   //提前打表存好各个数的因子        for(int j=i;j<maxn;j+=i)          {                s[j].push_back(i);          }              int n;    int kase=0;    int T;    cin>>T;    while(T--)    {         cin>>n;        inint(maxn);  //别忘了重建集合        for(int i=0;i<n;i++)        {           scanf("%d",&a[i]);            for(int j=0;j<s[a[i]].size();j++)//自此a[i]的因子全是一伙的                unit(a[i],s[a[i]][j]);        }        memset(flag,0,sizeof(flag));        int ans=0;        for(int i=0;i<n;i++)        {int root=find(a[i]);     //此时用上并查集,看看他们是不是一伙的            if(flag[root]==0)   //未被标记过就加数            {                ans++;                 if(a[i]!=1)    //一定别忘了1这位老兄,就是个光棍,                  flag[root]=1;  //给这一伙标记            }        }       printf("Case %d: %d\n",++kase,ans);    }    return 0;}


0 0
原创粉丝点击