日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

数据结构实验:连通分量个数

發(fā)布時(shí)間:2024/8/23 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构实验:连通分量个数 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目描述

?在無(wú)向圖中,如果從頂點(diǎn)vi到頂點(diǎn)vj有路徑,則稱vi和vj連通。如果圖中任意兩個(gè)頂點(diǎn)之間都連通,則稱該圖為連通圖, 否則,稱該圖為非連通圖,則其中的極大連通子圖稱為連通分量,這里所謂的極大是指子圖中包含的頂點(diǎn)個(gè)數(shù)極大。 例如:一個(gè)無(wú)向圖有5個(gè)頂點(diǎn),1-3-5是連通的,2是連通的,4是連通的,則這個(gè)無(wú)向圖有3個(gè)連通分量。 ?

輸入

?第一行是一個(gè)整數(shù)T,表示有T組測(cè)試樣例(0 < T <= 50)。每個(gè)測(cè)試樣例開(kāi)始一行包括兩個(gè)整數(shù)N,M,(0 < N <= 20,0 <= M <= 200) 分別代表N個(gè)頂點(diǎn),和M條邊。下面的M行,每行有兩個(gè)整數(shù)u,v,頂點(diǎn)u和頂點(diǎn)v相連。

輸出

?每行一個(gè)整數(shù),連通分量個(gè)數(shù)。

示例輸入

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];//標(biāo)記圖的頂點(diǎn)是否訪問(wèn)過(guò);
void dfs(MG &g,int i)//深度優(yōu)先搜索;
{
? ? int j;//j在函數(shù)內(nèi)部,不然不能回溯;
? ? 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;//記錄連通分量個(gè)數(shù);
void dfs1(MG &g)//統(tǒng)計(jì)連通分量的個(gè)數(shù)
{
? ? //int i;//若不在函數(shù)內(nèi)部不會(huì)回溯;
? ? 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));//標(biāo)記數(shù)組初始化;
? ? ? ? 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) { // 初始化各結(jié)點(diǎn)的 pre 為自身for(int i=0; i<=n; ++i) { // 相當(dāng)于初始時(shí)每個(gè)結(jié)點(diǎn)為各自獨(dú)立的集合pre[i] = i;} }int Find(int a) { // 查找 a 所在集合的根結(jié)點(diǎn) rootint root = a; // root 初始化為其本身while(pre[root] != root) { // 當(dāng) root 的上級(jí)結(jié)點(diǎn)不是其本身root = pre[root]; // 令 root 為它的上級(jí)結(jié)點(diǎn),繼續(xù)查找}while(pre[a] != root) { // 再次遍歷,路徑壓縮int temp = pre[a];pre[a] = root; // 沿途結(jié)點(diǎn)直接指向到 roota = temp;}return root; }void Join(int a, int b) { // 將 a, b 結(jié)點(diǎn)所在的集合合并int root_a = Find(a); // 查找 a 所在集合的根結(jié)點(diǎn)int root_b = Find(b); // 查找 b 所在集合的根結(jié)點(diǎn)if(root_a != root_b) { // 如果 a, b 不在同一集合,則合并if(root_a > root_b) // 根結(jié)點(diǎn)下標(biāo)大的集合并入下標(biāo)小的集合pre[root_a] = root_b;else pre[root_b] = root_a;} }int Count(int n) { // 統(tǒng)計(jì)不相交集合的個(gè)數(shù)int cnt = 0; // 計(jì)數(shù)變量for(int i=1; i<=n; ++i) {int root = Find(i); // 找到一個(gè)集合if(root) { // 如果是第一次找到此集合cnt++; // 計(jì)數(shù)pre[root] = 0; // 此根節(jié)點(diǎn)置0,防止重復(fù)}}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; }

總結(jié)

以上是生活随笔為你收集整理的数据结构实验:连通分量个数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。