您的位置:首页 > 其它

用并查集求朋友圈数目

2014-08-22 10:50 197 查看
小米的一道面试题:

假如已知有n个人和m对好友关系,如果两个人是直接或者间接有好友关系,则认为他们属于同一个朋友圈。写程序判断里面有多少朋友圈。

例如:

n = 5, m = 3  r = {(1,2), (2, 3), (4, 5)}  1 2 3 是一个朋友圈, 4 5 是一个朋友圈。

所以输出是2

这道题用并查集来求解就非常容易了。关于并查集的内容,这篇文章写得非常好:

http://blog.csdn.net/dm_vincent/article/details/7655764#reply

根据这篇文章,写了一个求解方法,代码如下:

class UnionFind {
public:
UnionFind(int n) : cnt(n)
{
id = new int
;
for (int i = 0; i < n; i++)
id[i] = i;

size = new int
;
for (int i = 0; i < n; i++)
size[i] = 1;
}

~UnionFind()
{
delete[] id;
delete[] size;
}

// 返回连通组的个数
int count()
{
return cnt;
}

// 查找一个节点属于哪个组
int findSet(int a)
{
if (id[a] == a)
return a;
else
return id[a] = findSet(id[a]); // 查找的同时提高节点的高度
}

bool isSameSet(int a, int b)
{
int x = findSet(a); // 查找a的组号
int y = findSet(b); // 查找b的组号

return x == y; // 判断组号是否相同
}

void Union(int a, int b)
{
int x = findSet(a);
int y = findSet(b);

if (x != y)
{
if (size[x] < size[y])
{
id[x] = y;
size[y] += size[x];
}
else
{
id[y] = x;
size[x] += size[y];
}

cnt--; // 合并后组的数量-1
}
}

private:
int *id;
int *size;
int cnt;
};

int main()
{
UnionFind friends(5);

friends.Union(0, 1);
friends.Union(1, 2);
friends.Union(3, 4);

cout << "朋友圈数目:" << friends.count() << endl;

system("pause");
return 0;
}

运行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: