求图的强连通分量

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

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

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

#include<stdio.h>
#include<stdlib.h>
#define MAX_NUM    10
int 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");
		}
}


 

你可能感兴趣的:(求图的强连通分量)