连通性的判断:
可以用dfs遍历整个图,用一个count计数联通点的数量,如果count等于n,那么整个图就是连通的,那么就是我们要找的就是用什么方法,可以用dfs或者bfs,大体思路就是从一个点开始找,先判断是否遍历过,没有就找到它的关系点,再从关系点dp,遍历后将count加一,向下访问,如果连通就会遍历到所有点即count=n
int count = 0;
void dfs(Map G, int i)
{
int j = 0;
visited[i] = 1;
count++;
for(j=0; j<G.num; j++)
{
if(G.map[i][j]==1 && !visited[j])//i和j有关系相邻,并且j顶点没有被访问过
{
dfs(G, j);
}
}
}
寻找割点/割边:
割点:定义就是如果把这个点从图中去掉,图的连通性被改变,这样的点就叫做割点
定理:1.如果一个点是割点,那么它存在一个子节点V,V和V的后代点都没有其他路回到割点的源点。 2. 根节点如果有两个以上的子树,那么它就是一个割点
思路:
选择dfs从一个点开始搜,每次操作先把操作的深度给赋值到low num 再初始化孩子的数量为0,遍历每一个子节点,若果没访问过就先进行dfs(v,u),更新值判断割点
用num[n]表示dfs对点的访问顺序,搜索深度越大num[u]越大 用low[n]表示是否V点有回退边回到U的源点 详细的操作看代码
#include<iostream>
using namespace std;
int low[105],num[105],dfn=0;
bool iscut[105]; //是否割点
vector<int>G[105]; //vector存图
void dfs(int u,int f){ //f为u父节点
low[u]=num[u]=++dfn;
int child=0;
int i,j;
for(i=0;i<G[u].size();i++){ //对每一个子节点都要操作
int v=G[u][i];
if(!num[v]){ //未访问过此子
child++;
dfs(v,u);
low[u]=min(low[u],low[v]); //用后代更新low[u]的值
if(low[v]>=num[u]&&u!=1)
iscut[u]=true; //标记割点
}
else if(num[v]<num[u]&&v!=f) low[u]=min(low[u],num[v]);
}
if(u==1&&child>=2)//根节点
iscut[1]=true;
}