题目描述
输入
输出
示例输入
2
3 1
1 2
3 2
3 2
1 2
示例输出
2
1
提示
#include <iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
typedef struct arcnode
{
int adj;
}arcnode,adjmatrix[200][200];
typedef struct
{
adjmatrix a;
int vn;
int an;
}MG;
int create(MG &g,int n,int m)//生成邻接矩阵;
{
int i,j;
int v1,v2;
g.vn=n;
g.an=m;
for(i=1;i<=g.vn;i++)
for(j=1;j<=g.vn;j++)
g.a[i][j].adj=0;
for(i=1;i<=g.an;i++)
{
scanf("%d%d",&v1,&v2);
g.a[v1][v2].adj=1;
g.a[v2][v1]=g.a[v1][v2];
}
return 1;
}
int v[110];//标记图的顶点是否访问过;
void dfs(MG &g,int i)//深度优先搜索;
{
int j;//j在函数内部,不然不能回溯;
v[i]=1;
for(j=1;j<=g.vn;j++)
if(g.a[i][j].adj==1&&!v[j])
{
dfs(g,j);
}
}
int i,count;//记录连通分量个数;
void dfs1(MG &g)//统计连通分量的个数
{
//int i;//若不在函数内部不会回溯;
for(i=1;i<=g.vn;i++)
if(!v[i])
{
count++;
dfs(g,i);
}
}
int main()
{
int t;
MG g;
scanf("%d",&t);
while(t--)
{
count=0;
memset(v,0,sizeof(v));//标记数组初始化;
int n,m;
scanf("%d%d",&n,&m);
create(g,n,m);
dfs1(g);
printf("%d\n",count);
}
return 0;
}
#include <cstdio>
#define MAX 2000
using namespace std;
int pre[MAX+1];
void Initialize(int n) { // 初始化各结点的 pre 为自身
for(int i=0; i<=n; ++i) { // 相当于初始时每个结点为各自独立的集合
pre[i] = i;
}
}
int Find(int a) { // 查找 a 所在集合的根结点 root
int root = a; // root 初始化为其本身
while(pre[root] != root) { // 当 root 的上级结点不是其本身
root = pre[root]; // 令 root 为它的上级结点,继续查找
}
while(pre[a] != root) { // 再次遍历,路径压缩
int temp = pre[a];
pre[a] = root; // 沿途结点直接指向到 root
a = temp;
}
return root;
}
void Join(int a, int b) { // 将 a, b 结点所在的集合合并
int root_a = Find(a); // 查找 a 所在集合的根结点
int root_b = Find(b); // 查找 b 所在集合的根结点
if(root_a != root_b) { // 如果 a, b 不在同一集合,则合并
if(root_a > root_b) // 根结点下标大的集合并入下标小的集合
pre[root_a] = root_b;
else pre[root_b] = root_a;
}
}
int Count(int n) { // 统计不相交集合的个数
int cnt = 0; // 计数变量
for(int i=1; i<=n; ++i) {
int root = Find(i); // 找到一个集合
if(root) { // 如果是第一次找到此集合
cnt++; // 计数
pre[root] = 0; // 此根节点置0,防止重复
}
}
return cnt;
}
int main(int argc, char const *argv[]) {
int t, n, m, u, v;
scanf("%d", &t);
while(t--) {
scanf("%d %d", &n, &m);
Initialize(n);
while(m--) {
scanf("%d %d", &u, &v);
Join(u, v);
}
printf("%d\n", Count(n));
}
return 0;
}
本文介绍了一种计算无向图连通分量数量的方法,通过深度优先搜索算法和并查集算法实现,适用于解决图论问题中的连通性分析。
3436

被折叠的 条评论
为什么被折叠?



