今天是Ignatius的生日,他邀请了很多朋友,现在是吃晚饭的时候了,Ignatius想知道他至少需要几张桌子。你必须注意到,并不是所有的朋友都认识对方,所有的朋友都不想和陌生人在一起。
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,D知道E,所以A,B,C可以呆在一张桌子上,D,E必须呆在另一张桌子上。所以Ignatius至少需要两张桌子。
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相互认识。两组测试之间会有一行空白。
For each test case, just output how many tables Ignatius needs at least. Do NOT print any blanks.
对于每组测试,只需输出Ignatius至少需要多少张桌子。不要打印任何空格。
Sample Input
解题思路:
1,第一次写这道题,方法比较麻烦,运行时间比较长,但是容易理解,这题的测试数组不是太大,可以通过;
2,第二次写这道题,采用了并查集的思想,还有一个set函数,代码运行时间短
set函数功能: 去重 排序
具体使用方法可以看:STL-集合-【set】
代码1:
#include<iostream>
using namespace std;
int main()
{
int t,s[1005],m,n,a,b,c,x;
cin>>t;
while(t--)
{
cin>>n>>m;
x=n; //x用来记录人数
for(int i=1;i<=n;i++)
s[i]=i; //数组初始化
while(m--)
{
cin>>a>>b;
if(a>b){c=a;a=b;b=c;}
c=s[a]; //用c保存s[a],下面循环内所有等于c的就证明
s[a]=s[b]; //把s[b]的值赋给s[a],就是让认识的人的值全部变为这些人的最大值
for(int i=1;i<=n;i++)
{
if(s[i]==c)
s[i]=s[b]; //如果有人的值等于c,证明他们和a,b认识,全部变为这些人中的最大值
}
}
for(int i=1;i<=n;i++) //这个循环是在统计这个数组内不一样的数字个数,即所求最少桌子数
{
for(int j=1;j<i;j++)
{
if(s[i]==s[j])
{
x--;
break;
}
}
}
cout<<x<<endl;
}
}
代码2:
#include<set>
#include<iostream>
using namespace std;
int N,M,Q;
int s[1005];
void initset() //数组初始化
{
for(int i=1;i<=M;i++)
s[i]=i;
}
int findset(int x) //寻找并查集的根
{
while(x!=s[x])
x=s[x];
return x;
}
int unionset(int x,int y) //把两个元素合到一个集合
{
if(x!=y)
s[x]=y;
}
int main(){
int a,b,sa,sb,t;
cin>>N;
while(N--){
cin>>M>>Q;
initset();
while(Q--){
cin>>a>>b;
sa=findset(a); //寻找根
sb=findset(b);
unionset(sa,sb); //合并
}
set<int>self; //声明一个set容器self,存储int类型的数据
for(int i=1;i<=M;i++)
{
s[i]=findset(s[i]); //一遍循环,寻找到所有值的根;
self.insert(s[i]); //把元素插入self集合中
}
t=self.size(); //由于set函数的去重排序功能,t即所求最少桌子数
cout<<t<<endl;
}
return 0;
}