首页 > ACM题库 > HDU-杭电 > HDU 1213 How Many Tables-并查集-[解题报告] C++
2013
12-04

HDU 1213 How Many Tables-并查集-[解题报告] C++

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.

样例输入:

2
5 3
1 2
2 3
4 5

5 1
2 5

样例输出:

2
4

 

 

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

#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
using namespace std;
int p[1010];
int getfather(int n)
{
    while(n!=p[n])
       n=p[n];
    return n;
}
void Union(int x,int y)
{
    int rootx=getfather(x);
    int rooty=getfather(y);
    if(rootx!=rooty)
       p[rooty]=rootx;
}
void inti(int n)
{
    for(int i=1;i<=n;i++)
     p[i]=i;
}
int main()
{
    int T,m,n,i;
     scanf("%d",&T);
       while(T--)
       {
          scanf("%d%d",&n,&m);
           inti(n);
           int a,b;
          for(i=1;i<=m;i++)
          {
              scanf("%d%d",&a,&b);
              Union(a,b);
          }
          int c=0;
          for(i=1;i<=n;i++)
            if(p[i]==i)
               c++;
          printf("%d\n",c);
          getchar();  //  这一步比较关键,我开始一直没注意到,无线wa,坑爹啊。
        }
    return 0;
}

 

这一题也是并查集的问题。

最基本的三个函数:getfather,Union,inti;

然后在主程序中判断,要是p[i]=i,那么他就是根节点,

根节点的个数就是集合的个数。

 


  1. 第一句可以忽略不计了吧。从第二句开始分析,说明这个花色下的所有牌都会在其它里面出现,那么还剩下♠️和♦️。第三句,可以排除2和7,因为在两种花色里有。现在是第四句,因为♠️还剩下多个,只有是♦️B才能知道答案。

  2. if(j){
    int ans=a ;
    for(int x=j-1;x>=0;x–){
    if(!a ) break;
    ans=min(ans,a );
    sum+=ans;
    }
    }
    求解释,,dp的思路是什么呢?