题目描述
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
6 4
1 2
2 3
3 4
1 4
8 10
1 2
2 3
5 6
7 5
4 6
3 6
6 7
2 5
2 4
4 3
样例输出
3
2
题意很简单,n个节点,m条边,问这n个点可以分成几组。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=1005;
int far[N];
bool vis[N];
int finf(int x)
{
int a=x;
vis[a]=true;
while(x!=far[x]) x=far[x];
while(a!=far[a])
{
vis[a]=true;
int z=a;
a=far[a];
far[z]=x;
}
return x;
}
void uion(int a,int b)
{
int fa=finf(a);
int fb=finf(b);
if(fa!=fb) far[fa]=fb;
}
int main()
{
int n,m,t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
int a,b;
for(int i=1;i<=n;i++)
far[i]=i;
for(int i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
uion(a,b);
}
// memset(vis,false,sizeof(vis));
// for(int i=1;i<=n;i++)
// {
// if(!vis[i])
// finf(i);
// }
int ans=0;
for(int i=1;i<=n;i++)
{
// printf("%d ",far[i]);
if(far[i]==i)
ans++;
}
printf("%d\n",ans);
}
}
为了提高传送效率和节约资源,要求当消息在某个端点生成后,其余各个端点均能接收到消息,并且每个端点均不会重复收到消息。
现给你通信系统的描述,你能判断此系统是否符合以上要求吗?
输入
每组输入首先包含2个整数N和M,N(1<=N<=1000)表示端点个数,M(0<=M<=N*(N-1)/2)表示通信线路个数。
接下来M行每行输入2个整数A和B(1<=A,B<=N),表示端点A和B由一条通信线缆相连。两个端点之间至多由一条线缆直接相连,并且没有将某个端点与其自己相连的线缆。
当N和M都为0时,输入结束。
输出
样例输入
4 3
1 2
2 3
3 4
3 1
2 3
0 0
样例输出
Yes
No
题意:n个点,m条边,问这些点能不能组成一棵树。
坑点:题目说了这些点不能组成环(每个端点不会收到重复的消息)
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=1005;
int far[N];
//bool vis[N];
int finf(int x)
{
// vis[x]=true;
int a=x;
while(x!=far[x]) x=far[x];
while(a!=far[a])
{
// vis[a]=true;
int z=a;
a=far[a];
far[z]=x;
}
// printf("%d ",x);
return x;
}
void uion(int a,int b)
{
int fa=finf(a);
int fb=finf(b);
if(fa!=fb)
far[fa]=fb;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m)&&(m+n))
{
// memset(vis,false,sizeof(vis));
int a,b,flag=1;
for(int i=1;i<=n;i++)
far[i]=i;
for(int i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
uion(a,b);
}
if(m>=n)//判断是否是环
{
printf("No\n");
continue;
}
for(int i=2;i<=n;i++)
{
// printf("%d ",finf(i));
if(finf(i)!=finf(i-1))
{
flag=0;
printf("No\n");
break;
}
}
if(flag)
printf("Yes\n");
}
}
题目描述
Mr Wang wants some boys to help him with a project. Because the project is rather complex, the more boys come, the better it will be. Of course there are certain requirements.Mr Wang selected a room big enough to hold the boys. The boy who are not been chosen has to leave the room immediately. There are 10000000 boys in the room numbered from 1 to 10000000 at the very beginning. After Mr Wang's selection any two of them who are still in this room should be friends (direct or indirect), or there is only one boy left. Given all the direct friend-pairs, you should decide the best way.
输入
The first line of the input contains an integer n (0 ≤ n ≤ 100 000) - the number of direct friend-pairs. The following n lines each contains a pair of numbers A and B separated by a single space that suggests A and B are direct friends. (A ≠ B, 1 ≤ A, B ≤ 10000000)
输出
The output in one line contains exactly one integer equals to the maximum number of boys Mr Wang may keep.
样例输入
3
1 3
1 5
2 5
4
3 2
3 4
1 6
2 6
样例输出
4
5
题意:n条边,问这些树中的最大节点个数是多少。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=100000;
int far[N+5],sum[N+5],ans=0;
bool vis[N];
int fin(int x)
{
if(far[x]!=x) far[x]=fin(far[x]);//路径压缩
return far[x];
// return far[x]==x?far[x]:far[x]=fin(far[x]);
}
//这也是路径压缩
//int fin(int x)
//{
// int a=x;
// while(x!=far[x]) x=far[x];
// while(a!=far[a])
// {
// int z=a;
// a=far[a];
// far[z]=x;
// }
// return x;
//}
void uion(int a,int b)
{
int fa=fin(a);
int fb=fin(b);
if(fa!=fb)
{
far[fb]=fa;
sum[fa]+=sum[fb];
ans=max(ans,sum[fa]);//更新根节点最大值
}
}
int main()
{
int n;
while(~scanf("%d",&n))
{
if(!n)
{
printf("1\n");
continue;
}
for(int i=1;i<=N;i++)
far[i]=i,sum[i]=1;
ans=0;
int a,b,num=0;
for(int i=0;i<n;i++)
{
scanf("%d%d",&a,&b);
// num=max(num,a);
// num=max(num,b);
uion(a,b);
}
printf("%d\n",ans);
}
}