並查集(How Many Tables)

在初高中數學中我們都學過集合,也就知道集合的交集和並集。所以思路應該很明確,但是用代碼表示要注意一下幾個坑:

1)兩個集合中可能有重複的元素,一定要查重;

 

2)兩個集合合併,一定要將兩個集合的所有元素都歸到一個集合內;

 用一個經典的查並集算法題來解釋一下

How Many Tables(並查集)

 

Link:http://acm.hdu.edu.cn/showproblem.php?pid=1213

題目:

Today is Ignatius’ birthday. He invites a lot of friends. Now it’s dinner time. Ignatius wants to know how many tables he needs at least. You have to notice that not all the friends know each other, and all the friends do not want to stay with strangers.

One important rule for this problem is that if I tell you A knows B, and B knows C, that means A, B, C know each other, so they can stay in one table.

For example: If I tell you A knows B, B knows C, and D knows E, so A, B, C can stay in one table, and D, E have to stay in the other one. So Ignatius needs 2 tables at least.

Input

The input starts with an integer T(1<=T<=25) which indicate the number of test cases. Then T test cases follow. Each test case starts with two integers N and M(1<=N,M<=1000). N indicates the number of friends, the friends are marked from 1 to N. Then M lines follow. Each line consists of two integers A and B(A!=B), that means friend A and friend B know each other. There will be a blank line between two cases.

Output

For each test case, just output how many tables Ignatius needs at least. Do NOT print any blanks.

Sample Input


5 3 
1 2 
2 3 
4 5

5 1 
2 5

Sample Output

4

思路:每個人是一個數組,兩個數組內存的數如果相同,代表認識併成爲一桌;(每個數組內剛開始都是自身編號)

給你們一組特殊測試數據:

輸入:

1

5 4

1 2

1 3

4 3

3 4

輸出:

2

代碼內部講解:

#include<iostream>
#include<cstdio>
int s[1005];
int n,m,i;
void chongzhi()//將每個人數組內的數重置一下  剛開始都是自身編號
{
    for(i=1;i<=n;i++)
    {
        s[i]=i;
    }
}
int bing(int x)//其實這個函數可以省略 只是爲了更加清晰
{
    if(x==s[x])//如果數組內的數跟自身相同 就返回自身的數
    {
        return x;
    }
    return bing(s[x]);//如果不同 返回數組內存的數
}
int he(int x,int y)
{
    int t1=x;
    int t2=y;
    int t;
    if(t1!=t2)//如果兩個數組的數不相同 將他們合併集合
    {
        t=s[t2];
        s[t2]=s[t1];
        for(i=1;i<=n;i++)//這個循環就是爲了將 兩個集合的所有元素合併 不僅僅是兩個元素合併
        {
            if(s[i]==t)
            {
                s[i]=s[t1];
            }
        }
    }

}
int main()
{
    int t,j,k,l;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d",&n,&m);//n個人 m個數據
        chongzhi();//調用上面的函數 將每個人數組內的數重置一下  剛開始都是自身編號
        int a,b;
        while(m--)
        {
            scanf("%d %d",&a,&b);
            s[a]=bing(a);
            s[b]=bing(b);
            he(s[a],s[b]);//合併集合
        }
        for(j=1;j<=n;j++)//排序
        {
            for(k=1;k<=n-j;k++)
            {
                if(s[k]>s[k+1])
                {
                    l=s[k];
                    s[k]=s[k+1];
                    s[k+1]=l;
                }
            }
        }
        l=1;
        for(j=1;j<n;j++)//查重
        {
            if(s[j]!=s[j+1])
                l++;
        }
        printf("%d\n",l);//輸出剩餘
    }
}


 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章