[ACM]hdu 1856 more is better 并查集

来源:互联网 发布:arm ubuntu 的启动参数 编辑:程序博客网 时间:2024/06/06 04:42

题目:hdu 1856 more is better
(http://acm.hdu.edu.cn/showproblem.php?pid=1856)
出错原因。
1.memset赋值问题
用了两个数组a[N],num[N],分别记录数字的根节点以及这个根节点上所带的集合的元素个数。
需要将数组num数组全部初始化为1 (自己即一个集合)
在用memset函数进行对num[N]进行初始化时,一开始初始化为0,答案全部为0。
后来意识到要初始化为1的时候改成:
memset(num,1,sizeof(num));
答案全部是大数,后来转换用最简单的方式初始化

    for(i=1;i<=N;i++)            num[i]=1;

输出就正确了。

原因是memset按字节赋值,而num是整数类型的,一个int元素是4字节,合一起是0000 0001,0000 0001,0000
0001,0000
0001,转化成十六进制就是0x01010101,就等于16843009,所以才会出现大数。所以在int类型时不可用memset赋值为1(若为char类型可以)。(百度)

以后还是在赋值为0再乖乖用memset吧。
2.超时问题。
em…删删减减换了很多种方式也没能解决这个问题。
把代码贴出来,如果有人能为我解答问题就太感谢了嘻嘻。

#include <iostream>#include <cstdio>#include <cstring>using namespace std;#define Max(a,b)  ((a)>(b)?(a):(b))#define N 1000005int a[N],num[N],ans;int find(int x){    if(a[x]==x)        return x;    return find(a[x]);}void Union(int x,int y)//x<y{    int m=find(x);    int n=find(y);    if(m!=n)    {        a[n]=m;        num[m]+=num[n];        ans = Max(ans, num[m]);    }}int main(){    int n,i;    while(scanf("%d",&n)!=EOF)    {        if (n==0)         {              printf("1\n");              continue;          }          int x,y;        ans=0;        for(i=1;i<=N;i++)        {            a[i]=i;            num[i]=1;        }        for(i=1;i<=N;i++)        {            scanf("%d%d",&x,&y);            Union(x,y);        }        printf("%d\n",ans);    }    return 0;}

3.
在程序运行之后,第二组数据无法输出结果,不知道原因。
本来用的是while(n–)的方式,虽然也是超时,但不会出现这种情况,同样好奇中。
4.
换了另外一个代码,在find 函数中,判定条件if(a[x]!=x)
和if(a[x]==x)两个的输出结果是不一样的,判定等于的结果少1。好奇的地方又+1.

原创粉丝点击