您的位置:首页 > 其它

HDU 1213 How Many Tables 并查集

2018-03-30 23:35 423 查看

题目:

http://acm.hdu.edu.cn/showproblem.php?pid=1213

题意:

有编号为1至n1至n的nn个人,其中有mm对朋友关系,间接的也算朋友关系,比如a↔ba↔b,b↔cb↔c,那么有a↔ca↔c。有朋友关系的人可以坐到一张桌子上。问现在最少需要多少张桌子

思路:

用并查集很简单。初始计数器置为nn,每次合并的时候,说明原本需要两张桌子的人可以坐到一张桌子上,于是计数器减一。最后输出计数器即可

代码:

#include <bits/stdc++.h>

using namespace std;

const int N = 1000 + 10;

int par
, Rank
;
int block;

void init(int n)
{
for(int i = 1; i <= n; ++i)
par[i] = i, Rank[i] = 1;
}
int Find(int x)//递归查找父节点,简洁
{
return par[x] = par[x] == x ? x : Find(par[x]);
}
//int Find(int x)//非递归查找
//{
//    int r = x, t;
//    while(par[r] != r) r = par[r];
//    while(par[x] != r) t = par[x], par[x] = r, x = t;
//    return r;
//}
void unite(int x, int y)
{
x = Find(x), y = Find(y);
if(x == y) return;
--block;
if(Rank[x] < Rank[y])
par[x] = y;
else
{
par[y] = x;
if(Rank[x] == Rank[y]) ++Rank[x];
}
}

int main()
{
int t, n, m;
scanf("%d", &t);
while(t--)
{
scanf("%d%d", &n, &m);
init(n);
block = n;
int a, b;
for(int i = 0; i < m; ++i)
{
scanf("%d%d", &a, &b);
unite(a, b);
}
printf("%d\n", block);
}

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