这是图遍历的一个经典应用
首先,什么是连通呢?
如果顶点A与顶点B之间有路径存在,则称A、B之间连通
如果一个图中,任意两点之间都连通,则称这个图为连通图
非连通图的极大连通子图,称为图的连通分量
注意:此处的连通分量不止一个哦
当我们学会图的深度与广度优先遍历后,这个问题就迎刃而解了
从上面的结果可以看出,
深度/广度遍历的每一行为一个连通分量
如果输出只有一行,则无向图具有连通性,否,则不具有连通性。
因此,将深度/广度遍历算法稍加修改,即可达到测试无向图连通性的功能
此处直接上代码(以深度优先搜索为例),
代码输入n,m分别代表顶点数,边数
输入m行,每行的u,v表示顶点u与v之间有边
输出结果为1行,表示无向图的连通分量个数
#include<bits/stdc++.h>
using namespace std;
const int mxn = 10005;
//图的存储:采用邻接表存储方式
class adjMatrixGraph
{
public:
adjMatrixGraph(int vsize);//构造函数 vsize代表顶点数,d[]数组表示顶点的名称A,B……
void insert(int u,int v);//插入函数,插入一条由x指向y的有向边
int judgeCon();//计算图的连通分量
~adjMatrixGraph();//析构函数
private:
int vers,edges;
struct edgeNode
{
int end;
edgeNode *next;
edgeNode(int e,edgeNode *n=NULL)
{
end=e;
next=n;
}
};
struct verNode
{
edgeNode *head;
verNode(edgeNode *h=NULL) {head=h;}
};
verNode *verList;//创建数组形式的节点表
void dfs(int v,bool visited[]);
};
//构造函数
adjMatrixGraph::adjMatrixGraph(int vsize)
{
vers=vsize;
edges=0;
verList=new verNode[vsize];
}
//析构函数
adjMatrixGraph::~adjMatrixGraph()
{
edgeNode *p;
for(int i=0;i<vers;i++)
{
while((p=verList[i].head)!=NULL)
{
verList[i].head=p->next;
delete p;
}
}
delete [] verList;
}
//插入函数
void adjMatrixGraph::insert(int u, int v)
{
verList[u].head=new edgeNode(v,verList[u].head);
++edges;
}
int adjMatrixGraph::judgeCon()
{
int count=0;
bool *visited=new bool[vers];
for(int i=0;i<vers;i++)
{
visited[i]=false;//初始化访问矩阵均为未访问
}
for(int i=0;i<vers;i++)
{
if(!visited[i])
{dfs(i,visited);
count++;}
}
return count;
}
void adjMatrixGraph::dfs(int v,bool visited[])
{
edgeNode *p=verList[v].head;
visited[v]=true;
while(p!=NULL)
{
if(visited[p->end]==false)
dfs(p->end,visited);
p=p->next;
}
}
int main(void){
int n,m;
cin>>n>>m;
adjMatrixGraph graph(n);
for(int i=0;i<m;i++){
int u,v;
cin>>u>>v;
// your code
graph.insert(u,v);
graph.insert(v,u);//上述图的存储为有向,要变为无向图,进行两次插入路径操作即可
}
cout<<graph.judgeCon()<<endl;
/
}