标签:style blog class c code tar
题目:
链接:点击打开链接
题意:
有n个朋友,编号为1......n。知道其中一些人相互认识,求最少需要多少桌子。
算法:
并查集算法的模板题。
(来源:LCY-teacher课件)
>>在某个城市里住着n个人,现在给定关于 n个人的m条信息(即某2个人认识)假设所有认识的人一定属于同一个单位,请计算该城市最多有多少单位?
>>如何实现?
>>什么是并查集?
>>英文:Disjoint Set,即“不相交集合”将编号分别为1…N的N个对象划分为不相交集合,在每个集合中,选择其中某个元素代表所在集合。常见两种操作:I.合并两个集合.II.查找某元素属于哪个集合
>>实现方法1:。用编号最小的元素标记所在集合;。定义一个数组set[1..n] ,其中set[i] 表示元素i 所在的集合。
find1(x)
{
return set[x];
}
Merge1(a,b)
{ i = min(a,b);
j = max(a,b);
for (k=1; k<=N; k++) {
if (set[k] == j)
set[k] = i;
}
}
>>考虑用树结构?
>>
merge2(a, b)
{
if (a<b)
set[b] = a;
else
set[a] = b;
}
find2(x)
{
r = x;
while (set[r] != r)
r = set[r];
return r;
}
最坏情况Θ(N)
>>避免最坏情况:
merge3(a,b)
{ if (height(a) == height(b)) {
height(a) = height(a) + 1;
set[b] = a;
} else if (height(a) < height(b))
set[a] = b;
else
set[b] = a;
}
find2(x)
{
r = x;
while (set[r] != r)
r = set[r];
return r;
}
find3(x)
{
r = x;
while (set[r] <> r) //循环结束,则找到根节点
r = set[r];
i = x;
while (i <> r) //本循环修改查找路径中所有节点
{
j = set[i];
set[i] = r;
i = j;
}
}
思路:
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,a,b,cnt;
int father[1010];
int getfather(int n)
{
while(n != father[n])
n = father[n];
return n;
}
void Union(int x,int y)
{
int rootx = getfather(x);
int rooty = getfather(y);
if(rootx != rooty)
father[rooty] = rootx;
}
int main()
{
//freopen("input.txt","r",stdin);
int t;
cin>>t;
while(t--)
{
getchar();
cnt = 0;
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
father[i] = i;
for(int i=1; i<=m; i++)
{
scanf("%d%d",&a,&b);
Union(a,b);
}
for(int i=1; i<=n; i++)
{
if(father[i] == i)
cnt++;
}
printf("%d\n",cnt);
}
return 0;
}
LR杂记 - loadrunner结果各种指标分析,布布扣,bubuko.com
标签:style blog class c code tar
原文地址:http://blog.csdn.net/a578133380/article/details/26171643