一、题目
输入以整数T(1<=T<=25)开始,表示测试用例的数量。接下来是T个测试用例。每个测试用例以两个整数N和M(1<=N,M<=1000)开头。N表示朋友的数量,从1到N标记朋友,然后M行跟随。每一行包含两个整数A和B(A!=B),意思是朋友A和朋友B互相认识。两个案子之间会有一个空行。不认识的朋友不在一张桌子,求至少需要多少桌子。
二、解析
- 找到x的掌门人
int find(int x) {
if (x == fa[x]) return x;
return fa[x] = find(fa[x]);//路径压缩
}
- 合并x和y所在的门派
void unite(int x, int y) {
int fx = find(x);
int fy = find(y);
if (fx == fy) return;
fa[fx] = fy;
}
- 查看x和y的门派是否相同
bool check(int x, int y) {
int fx = find(x);
int fy = find(y);
if (fx == fy) return true;
return false;
}
全部代码
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string>
#include<string.h>
#include<algorithm>
#include <vector>
using namespace std;
#define ll long long
#define sc(x) scanf("%d",&x)
#define scc(x, y) scanf("%d%d",&x,&y)
#define p(x) printf("%d\n",x)
#define m(x, y) (x+y)>>1
#define l(x) x<<1
#define r(x) x<<1|1
const int maxn = 1e5 + 6;
int fa[maxn];
int size[maxn];
int n;
//找到x的掌门人
int find(int x) {
if (x == fa[x]) return x;
return fa[x] = find(fa[x]);//路径压缩
}
//合并x和y所在的门派
void unite(int x, int y) {
int fx = find(x);
int fy = find(y);
if (fx == fy) return;
fa[fx]=fy;
}
//查看x和y的门派是否相同
bool check(int x, int y) {
int fx = find(x);
int fy = find(y);
if (fx == fy) return true;
return false;
}
int main() {
int t;
sc(t);
int m;
while (t--) {
scc(n, m);
//初始化
for (int i = 1; i <= n; i++) fa[i] = i;
int ans = 0;//ans是门派的数量
while (m--) {
int u, h;
scc(u, h);
unite(u, h);
}
//查询门派数量
for (int i = 1; i <= n; i++) if (fa[i] == i) ans++;
p(ans);
}
}
按秩合并
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string>
#include<string.h>
#include<algorithm>
#include <vector>
using namespace std;
#define ll long long
#define sc(x) scanf("%d",&x)
#define scc(x, y) scanf("%d%d",&x,&y)
#define p(x) printf("%d\n",x)
#define m(x, y) (x+y)>>1
#define l(x) x<<1
#define r(x) x<<1|1
const int maxn = 1e5 + 6;
int fa[maxn];
int size[maxn];
int n;
//找到x的掌门人
int find(int x) {
if (x == fa[x]) return x;
return fa[x] = find(fa[x]);//路径压缩
}
//合并x和y所在的门派
void unite(int x, int y) {
int fx = find(x);
int fy = find(y);
if (fx == fy) return;
//按秩合并
if (size[fx] < size[fy]) fa[fx] = fy, size[fy] += size[fx];
else fa[fy] = fx, size[fx] += size[fy];
}
//查看x和y的门派是否相同
bool check(int x, int y) {
int fx = find(x);
int fy = find(y);
if (fx == fy) return true;
return false;
}
int main() {
int t;
sc(t);
int m;
while (t--) {
scc(n, m);
//初始化
for (int i = 1; i <= n; i++) fa[i] = i, size[i] = 1;
int ans = 0;//ans是门派的数量
while (m--) {
int u, h;
scc(u, h);
unite(u, h);
}
//查询门派数量
for (int i = 1; i <= n; i++) if (fa[i] == i) ans++;
p(ans);
}
}