HDU More is better

2014-11-24 11:23:57 · 作者: · 浏览: 0

More is better

Time Limit:1000MS Memory Limit:102400KB 64bit IO Format:%I64d & %I64u Submit Status

Description

Mr Wang wants some boys to help him with a project. Because the project is rather complex, the more boys come, the better it will be. Of course there are certain requirements.Mr Wang selected a room big enough to hold the boys. The boy who are not been chosen has to leave the room immediately. There are 10000000 boys in the room numbered from 1 to 10000000 at the very beginning. After Mr Wang's selection any two of them who are still in this room should be friends (direct or indirect), or there is only one boy left. Given all the direct friend-pairs, you should decide the best way.

Input

The first line of the input contains an integer n (0 ≤ n ≤ 100 000) - the number of direct friend-pairs. The following n lines each contains a pair of numbers A and B separated by a single space that suggests A and B are direct friends. (A ≠ B, 1 ≤ A, B ≤ 10000000)

Output

The output in one line contains exactly one integer equals to the maximum number of boys Mr Wang may keep.

Sample Input

4
1 2
3 4
5 6
1 6
4
1 2
3 4
5 6
7 8

Sample Output

4
2

Hint

A and B are friends(direct or indirect), B and C are friends(direct or indirect), 
then A and C are also friends(indirect).

 In the first sample {1,2,5,6} is the result.
In the second sample {1,2},{3,4},{5,6},{7,8} are four kinds of answers.
[cpp] view plaincopyprint 在CODE上查看代码片 派生到我的代码片
  1. [cpp] view plaincopyprint 在CODE上查看代码片派生到我的代码片
    1. 简单的并查集题目:

      WA了好几次的代码:

      [html] view plaincopyprint 在CODE上查看代码片派生到我的代码片
      1. #include
      2. #include
      3. using namespace std;
      4. int father[10000010];
      5. int num[10000010];
      6. int Max;
      7. int Find(int x)
      8. {
      9. if(x!=father[x])
      10. father[x]=Find(father[x]);
      11. return father[x];
      12. }
      13. void merset(int x,int y)
      14. {
      15. int q=Find(x);
      16. int p=Find(y);
      17. if(q!=p)
      18. {
      19. num[y]=num[x]+num[y];
      20. num[x]=num[y];
      21. if(num[x]>Max)
      22. Max=num[x];
      23. if(q>p)
      24. father[q]=p;
      25. else
      26. father[p]=q;
      27. }
      28. }
      29. void Init()
      30. {
      31. for(int i=1;i<=10000000;i++)
      32. {
      33. father[i]=i;
      34. num[i]=1;
      35. }
      36. }
      37. int main()
      38. {
      39. int n;
      40. while(~scanf("%d",&n))
      41. {
      42. Init();
      43. Max=num[1];
      44. while(n--)
      45. {
      46. int x,y;
      47. scanf("%d%d",&x,&y);
      48. merset(x,y);
      49. }
      50. cout< }
      51. return 0;
      52. }

        之后通过画图,单步跟踪,还有请教学长终于找出了错误来源:


        x y 可以理解成当前要合并的两个集合,但是他们又不一定不是两个树根 P Q则是find路径压缩后他们的树根(可能是他们本身也可能是别的)他们两个还有子树指向它们,加X Y的数量 max就只能是他们子树的数量加起来 而不是他们合并的那个最大数量。

        每次都只是更新了某个子树上的全部数量
        (第一次是准确的)但是根树上的节点没有再次更新。。。每次子树变动 即合并的子节点不同 就会有损失。
        试下1 2 2 3 1 4 第一次更新num[1]=num[2]=2;第二次就是num[2]=num[3]=3;但此次num[1]还是2 第三次 就是num[1]=num[4]=3 ,损失了一个。。。

        如果一直更新根数 就是num[1]=num[2]=2,num[1]=num[3]=3;num[1]=num[4]=4。


        正确代码: [cpp] view plaincopyprint 在CODE上查看代码片派生到我的代码片
        1. #include
        2. #include
        3. using namespace std;
        4. int father[10000010];
        5. int num[10000010];
        6. int Max;
        7. int Find(int x)
        8. {
        9. if(x!=father[x])
        10. father[x]=Find(father[x]);
        11. return father[x];
        12. }
        13. void merset(int x,int y)
        14. {
        15. int q=Find(x);
        16. int p=Find(y);
        17. if(q!=p)
        18. {
        19. num[p]=num[q]+num[p];
        20. num[q]=num[p];
        21. if(num[q]>Max)
        22. Max=num[q];
        23. if(q>p)
        24. father[q]=p;
        25. else
        26. father[p]=q;
        27. }
        28. }
        29. void Init()
        30. {
        31. for(int i=1;i<=10000000;i++)
        32. {
        33. father[i]=i;
        34. num[i]=1;
        35. }
        36. }
        37. int main()
        38. {
        39. int n;
        40. while(~scanf("%d",&n))
        41. {
        42. Init();
        43. Max=num[1];
        44. while(n--)
        45. {
        46. int x,y;
        47. scanf("%d%d",&x,&y);
        48. merset(x,y);
        49. }
        50. cout< }
        51. return 0;
        52. } [cpp] view plaincopyprint
          1. 特别感谢浩浩学长的耐心指导~