判断图的连通性

关于判断一个图的连通性有几种方法,下面为大家介绍几种简单的方法,好记又方便,难得我会提下(毕竟自己很菜,不会),大家想了解更多的可以自己百度

简单:1,可以用广搜遍历图(用邻接矩阵存的),若图能连通,那么比能访问完所有图中节点,核心代码如下:

 

<span style="font-size:14px;color:#FF0000;"><strong>//申明邻接矩阵是用mapp[][]二维数组存的,当mappp[i][j]不等于0时表示i-j,j-i是有路连接的</strong></span>
bool liantong()
{
 	int count,i,v;
	queue<int> q; 
	memset(mark,0,sizeof(mark));//初始化为0
 	count = 0;
 	q.push(1); 
        mark[1]=1;
 	while(!q.empty()){
   		v=q.front();q.pop();
  		mark[v] = 1;//mark为标记数组,1为入队,0表示还未入队,初始化为0
  		count++;
	for (i=1;i<=n;i++)
   	if (mapp[v][i]!=0&&!mark[i]){
    	 q.push(i);
    	 mark[i]=1;///这个不可少,
    	}
    }
 if (count == n) 
     return true;//如果次数等于图的点数,则连通
 else 
     return false;//否则不连通
}

2.用深度优先搜索,道理也一样

 

 

int mapp[1000][1000],mark[1000],n;
void dfs_visit(int u){
 	mark[u] = 1;
 	for(i=0; i<n;i++)
  		if(mapp[u][i]!=0&&mark[i]==0)
   		dfs_visit(i);
}
bool liantong(adjGraph G){
	int i;
 	memset(mark,0,sizeof(mark));
 	dfs_visit(1); ///图中的编号从1开始 
 	///遍历图后若发现有mark[i]等于初始化时的0,说明存在着没被访问的点 
 	for(i=0;i<n;i++)
  		if(mark[i]==0)  
		  return false;
 	return true;
}
3.矩阵乘法:<span style="color:#FF0000;">除了主对角线外,其余均为1则表示图是连通的</span>
int mapp[1000][1000],temp[1000][1000],mark[1000],n;
bool laintong(){
 	int i,j,k;
 	for(i=0;i<n;i++)
 		for(j=0;j<n;j++)
 			temp[i][j]=mapp[i][j];
	for (i=0;i<n;i++){
  		for(j=0;j<n;j++){
   			if (mapp[i][j]==1)
    			temp[i][j]=1;
   			else
    			temp[i][j]=0;

  		}
  		temp[i][i]=1;//<span style="color:#FF0000;">/把主对角线也置1了</span>
 	}
	//矩阵乘法算法
 	for(i=0;i<n;i++)
  		for(j=0;j<n;j++)
   			if(temp[i][j]==1){
    			for(k=0;k<n;k++)
     				if(temp[k][i]==1)
      				temp[k][j]=1;
    		}
 	//每个点都为1则连通
	for (i=0;i<n;i++)
  		for (j=0;j<n;j++)
   			if (temp[i][j]==0)
    		return false;
 	return true;
}

 

4,拓扑算法(多用于有向图)写过一个关于拓扑的代码戳点击打开链接

mapp[i][j]=1,则r[j]++;

 

int mapp[1000][1000],r[1000](统计每个点的入度)c[1000](存按顺序找出的入度为0的点),n,l=1;
bool liantong(){
for(i=1;i<=n;i++)//遍历n次  
        for(j=1;j<=n;j++)  
        if(r[j]==0){  //发现入度为0的点
            r[j]--;  //删除度为0的点,防止下次被重复的找到
            c[l++]=j; //把点存在数组里 
            //把和j想连的点的入度减1,即删除所有与j有联系的点。
            for(k=1;k<=n;k++)  
            if(mapp[j][k])  
            r[k]--;  
            break;  
        }  
       //这里按1开始存吧
        printf("%d",c[1]);  
        for(i=2;i<=l;i++)  
        printf(" %d",c[i]);  
        printf("\n");  
    }  
    for(i=1;i<=n;i++)
       if(i!=c[i])
       return false;
    return true;
}

我觉得难得,可能是因为他的图是邻接表存的,,,请戳这个大神的博客点击打开链接
我要好好看邻接表了,看了2次了,总感觉似懂非懂!!!

 


 

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值