题解报告:hdu 1213 How Many Tables

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

Problem Description

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.

译文:今天是伊格内修斯的生日。他邀请了很多朋友。现在是晚餐时间。伊格内修斯想知道他至少需要多少张桌子。你必须注意,并非所有的朋友都彼此认识,所有的朋友都不想和陌生人呆在一起。这个问题的一个重要原则是,如果我告诉你A知道B,B知道C,那就意味着A,B,C彼此了解,所以他们可以呆在一张桌子里。例如:如果我告诉你A知道B,B知道C,D知道E,那么A,B,C可以留在一张桌子上,而D,E必须留在另一张桌子上。所以Ignatius至少需要2张牌桌

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.

译文:输入以表示测试用例数的整数T(1 <= T <= 25)开始。然后是T测试用例。每个测试用例以两个整数N和M(1 <= N,M <= 1000)开始。N表示朋友的数量,朋友被标记从1到N.然后是M行。每行由两个整数A和B(A!= B)组成,这意味着朋友A和朋友B彼此了解。两种情况之间会有空白。

Output

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

译文:对于每个测试用例,只需输出Ignatius至少需要的表格数量。不要打印任何空白。

Sample Input

2
5 3
1 2
2 3
4 5
 
5 1
2 5
Sample Output
2
4
解题思路:题目的意思就是求有多少个最大连通图,采用并查集的方法,将有关系的合并成一个集合,存放每个节点的father数组全部初始化为-1(默认为根节点)。father数组也可以初始化成自身值,因为每个最大的连通图中必有一个节点的根节点为自身值,所以也可以根据这点来查看有多少个最大连通图。
AC代码:
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1005;
 4 int t,n,m,a,b,father[maxn];
 5 int find_father(int x){//找根节点
 6     if(father[x]==-1)return x;//如果根节点是-1,返回此时的节点编号
 7     else return father[x]=find_father(father[x]);//递归查找根节点
 8 }
 9 void unite(int x,int y){
10     x=find_father(x);
11     y=find_father(y);
12     if(x!=y)father[x]=y;//如果不是同一个连通图,则可以合并
13 }
14 int main()
15 {
16     while(cin>>t){
17         while(t--){
18             memset(father,-1,sizeof(father));//先默认-1为各节点的根节点,跟往常的不一样,因为此题求解是有多少个强连通图
19             cin>>n>>m;//n表示节点个数,m表示有m种情况
20             while(m--){
21                 cin>>a>>b;
22                 unite(a,b);//读入时顺便合并
23             }
24             int ans=0;
25             for(int i=1;i<=n;++i)
26                 if(father[i]==-1)++ans;//有多少个根节点是-1,就有多少个最大连通子图
27             cout<<ans<<endl;
28         }
29     }
30     return 0;
31 }

猜你喜欢

转载自www.cnblogs.com/acgoto/p/9056697.html