HDU1213基础并查集

来源:互联网 发布:最小公倍数的算法 编辑:程序博客网 时间:2024/06/05 13:28

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.

输入:

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.

输出:

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

样例输入:

25 31 22 34 55 12 5

样例输出:

24
学习并查集写的第一个题目,并查集有模板滴~记住(当然还要会用)但是对于小白的我来说,还不是太会用啦。后面有一道题有一点点改动,但我还是不会啊,只能先进行模仿咯~我看有些博客里面写的find函数,没有使用路径优化,有些则写了,我也不知道要不要写,所以就都写了。路径优化感觉有点看不太懂啊= =

代码:(模板~~~)

#include<iostream>

using namespace std;
int pre[1001];
int find(int x)
{
    int r=x;
    while(pre[r]!=r)
    r=pre[r];
    //路径优化
    int i=x,j;
    while(i!=r)
    {
    j=pre[i];
    pre[r]=r;
    i=j;    
    }
    return r;    
}
void join(int x,int y )
{
    int fx=find(x),fy=find(y);
    if(fx!=fy)
    pre[fx]=fy;
}
int main()
{
int k,a,b,n,m,x,y;
cin>>k;
for(int i=0;i<k;i++)
{
//一共有n个人,m行代表m个认识的人
cin>>n>>m;
for(int i=1;i<=n;i++)
{
pre[i]=i;    
}
for(int i=0;i<m;i++)
{
    cin>>a>>b;
    x=find(a);
    y=find(b);
    if(x!=y) join(x,y);
}
int ans=0;
for(int i=1;i<=n;i++)
{
    if(pre[i]==i) ans++;
}
cout<<ans<<endl;
}    

}


0 0
原创粉丝点击