判断图的连通性

来源:互联网 发布:百度快照seo 编辑:程序博客网 时间:2024/04/27 02:20

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

简单: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次了,总感觉似懂非懂!!!大哭大哭,明天的你请加油



0 0