求图的强连通分量

来源:互联网 发布:网络列头柜布线 编辑:程序博客网 时间:2024/06/01 10:19

深度优先遍历是求图的强连通分量的一个有效方法。其思路大概如下:

1)在有向图上,以某一顶点进行深度优先遍历,并按其所有邻接顶点都完成(退出DFL函数)顺序将顶点排列起来。即在结束函数之前,用数组存储该顶点

2)将图转置,从数组最后一顶点开始,再次进行深度优先收索。每退出函数,即是一个顶点集

#include<stdio.h>#include<stdlib.h>#define MAX_NUM    10int a[MAX_NUM];                      //用来存放深度优先收索结点序列(本来应该就用栈的,此处简单一点用数组来存)int w=0;typedef struct  ArcNode              //图的弧结点{int adjvex;             //该弧所指向的顶点信息struct ArcNode *next;}ArcNode;typedef struct                   //图的顶点结点{char data;ArcNode *first;         //指向第一条依附该结点的图}VNode,AdjList[MAX_NUM];typedef struct                    //图结构 {int vexnum,arcnum;      //顶点,弧的个数AdjList  vertices;      //顶点结点数组}MGraph;void create(MGraph **g1,MGraph **g2,int n,int m);          //创建图                                             void insert(MGraph *g, int l1,int l2);            //插入弧void DSL(MGraph *g,int visited[],int i,int sign);  //深度优先遍历图void research(MGraph *g);void research1(MGraph *g);void main(){int n,m;MGraph *g1,*g2;printf("输入顶点和弧的个数:\n");scanf("%d%d",&n,&m);create(&g1,&g2,n,m);printf("输出深度优先搜索顺序:\n");research(g1);printf("\n");printf("以行为单位输出强连通分量:\n");research1(g2);printf("\n");}//插入弧结点信息void insert(MGraph *g,int l1,int l2) {ArcNode *p,*q;p=g->vertices[l1].first;if(!p)                          //当该弧尾原来是孤独结点{q=(ArcNode*)malloc(sizeof(ArcNode));q->adjvex=l2;q->next=NULL;g->vertices[l1].first=q;}else                           {while(p->next){p=p->next;}q=(ArcNode*)malloc(sizeof(ArcNode));q->adjvex=l2;q->next=NULL;p->next=q;}}//创建图信息void create(MGraph **g1,MGraph **g2,int n,int m){int i,l1,l2;*g1=(MGraph *)malloc(sizeof(MGraph));(*g1)->vexnum=n;(*g1)->arcnum=m;*g2=(MGraph *)malloc(sizeof(MGraph));(*g2)->vexnum=n;(*g2)->arcnum=m;printf("输入各节点为:\n");scanf(" ");for(i=0;i<=n;i++){scanf("%c",&(*g1)->vertices[i].data);(*g1)->vertices[i].first=NULL;(*g2)->vertices[i].data=(*g1)->vertices[i].data;(*g2)->vertices[i].first=NULL;}printf("输入各弧信息:\n");for(i=0;i<m;i++){scanf("%d-%d",&l1,&l2);insert(*g1,l1,l2);                 //建立图insert(*g2,l2,l1);                 //建立逆向图}}//深度优先遍历void DSL(MGraph *g,int visited[],int i,int sign){ArcNode *p;int k;visited[i]=1;printf("%5c",g->vertices[i].data);//if(sign)//a[w++]=i;for(p=g->vertices[i].first;p;p=p->next){k=p->adjvex;if(!visited[k])DSL(g,visited,k,sign);}if(sign)a[w++]=i;}void research(MGraph *g)             //第一次深度优先搜索{int i;int visited[MAX_NUM];for(i=0;i<g->vexnum;i++)visited[i]=0;for(i=0;i<g->vexnum;i++)if(!visited[i])DSL(g,visited,i,1);}void research1(MGraph *g)            //第二次逆向深度优先搜索{int i;int visited[MAX_NUM];for(i=0;i<g->vexnum;i++)visited[i]=0;for(i=--w;i>=0;i--)if(!visited[a[i]]){DSL(g,visited,a[i],0);printf("\n");}}


 

原创粉丝点击