【HDU】How Many Tables (並查集模板題)

題目傳送門

題目描述:

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

2
5 3
1 2
2 3
4 5
5 1
2 5

Sample Output

2
4

很有意思的並查集~
看到一篇很有意思的博客,寫的很好,在這裏貼一下 (戳這裏

藉助這道題說一下並查集的原理,俗話說,朋友的朋友即是朋友,所以我們在聚會時,爲了減少桌子的用量,我們規定有這個麼關係的一羣人就可以坐在一張桌子,而若兩個同學不認識,他們也沒有互相認識的人,這樣他們就不可以坐一桌,爲了確定他們之間能不能做到一張桌子上,我們需要一個數組pre來標記我們每個人最好的朋友是誰,我們首先詢問我們的好朋友 是否認識某人,再通過詢問 朋友的好朋友 (以此類推)達到查詢的目的。

關於路徑壓縮算法

因爲最後形成的的樹形結構查找效率非常低下(舉個極端的栗子:比如說是一字蛇形陣),所以我們要把每個人的最後的祖先直接通過pre數組標記出來,例如,pre[3]=2 —> pre[3]=1;
所以路徑壓縮算法的思想就可以通過下圖表現出來:
在這裏插入圖片描述
奉上代碼:

#include<bits/stdc++.h>
#define N 10100
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=1e6+10;
int pre[maxn];
int unionserch(int root)
{
    int son,temp;
    son=root;
    while(root!=pre[root])//找祖先
    {
        root=pre[root];
    }
    while(son!=root)//路徑壓縮
    {
        temp=pre[son];
        pre[son]=root;
        son=temp;
    }
    return root;
}
int main()
{
    ios::sync_with_stdio(false);
    int n,m,t,x,y;
    cin>>t;
    while(t--)
    {
        cin>>n>>m;
        for(int i=1;i<=n;i++)
        pre[i]=i;
        for(int i=1;i<=m;i++)
        {
            cin>>x>>y;
            int bx=unionserch(x);
            int by=unionserch(y);
            if(bx!=by)
            pre[bx]=by;
        }
            int tol=0;
            for(int i=1;i<=n;i++)
            {
                if(pre[i]==i)
                   tol++;
            }
           cout<<tol<<endl;
    }
}

寫的有點粗糙,先貼出來吧,有時間再改QWQ~
這是第五個,剛把帶QAQ

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