数据结构实验:连通分量个数
題目描述
?在無向圖中,如果從頂點vi到頂點vj有路徑,則稱vi和vj連通。如果圖中任意兩個頂點之間都連通,則稱該圖為連通圖, 否則,稱該圖為非連通圖,則其中的極大連通子圖稱為連通分量,這里所謂的極大是指子圖中包含的頂點個數極大。 例如:一個無向圖有5個頂點,1-3-5是連通的,2是連通的,4是連通的,則這個無向圖有3個連通分量。 ?輸入
?第一行是一個整數T,表示有T組測試樣例(0 < T <= 50)。每個測試樣例開始一行包括兩個整數N,M,(0 < N <= 20,0 <= M <= 200) 分別代表N個頂點,和M條邊。下面的M行,每行有兩個整數u,v,頂點u和頂點v相連。輸出
?每行一個整數,連通分量個數。示例輸入
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 所在集合的根結點 rootint root = a; // root 初始化為其本身while(pre[root] != root) { // 當 root 的上級結點不是其本身root = pre[root]; // 令 root 為它的上級結點,繼續查找}while(pre[a] != root) { // 再次遍歷,路徑壓縮int temp = pre[a];pre[a] = root; // 沿途結點直接指向到 roota = 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; }
總結
以上是生活随笔為你收集整理的数据结构实验:连通分量个数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mongodb最详细的安装与配置
- 下一篇: 数据结构实验之栈六:下一较大值(二)