算法导论 强连通分量

来源:互联网 发布:韶关网络问政 编辑:程序博客网 时间:2024/04/17 06:19
#include <stdio.h>#include <stdlib.h>#define WHITE 0#define GRAY 1#define BLACK 2//CNT用于编号TOPO序列,CNT_GROUP用于编号groupint CNT,CNT_GROUP;//顶点类型,f是算导标准算法中的一个属性,这里其实可以省略typedef struct{int color;int group;char name;int f;}Vertex,*pVertex;//图类型,包含Topo排序数组typedef struct {int v_n;pVertex *V;int **E;int *TopoOrder;}Graph,*pGraph;//根据算导中的图22-9进行初始化pGraph initGraph(){pGraph g = (pGraph)malloc(sizeof(Graph));g->v_n=8;g->TopoOrder=(int*)malloc(g->v_n*sizeof(int));pVertex v1=(pVertex)malloc(sizeof(Vertex));v1->name='a';v1->group=-1;v1->color=WHITE;v1->f=0;pVertex v2=(pVertex)malloc(sizeof(Vertex));v2->name='b';v2->group=-1;v2->color=WHITE;v2->f=0;pVertex v3=(pVertex)malloc(sizeof(Vertex));v3->name='c';v3->group=-1;v3->color=WHITE;v3->f=0;pVertex v4=(pVertex)malloc(sizeof(Vertex));v4->name='d';v4->group=-1;v4->color=WHITE;v4->f=0;pVertex v5=(pVertex)malloc(sizeof(Vertex));v5->name='e';v5->group=-1;v5->color=WHITE;v5->f=0;pVertex v6=(pVertex)malloc(sizeof(Vertex));v6->name='f';v6->group=-1;v6->color=WHITE;v6->f=0;pVertex v7=(pVertex)malloc(sizeof(Vertex));v7->name='g';v7->group=-1;v7->color=WHITE;v7->f=0;pVertex v8=(pVertex)malloc(sizeof(Vertex));v8->name='h';v8->group=-1;v8->color=WHITE;v8->f=0;g->V = (pVertex *)malloc(g->v_n*sizeof(Vertex));g->V[0]=v1;g->V[1]=v2;g->V[2]=v3;g->V[3]=v4;g->V[4]=v5;g->V[5]=v6;g->V[6]=v7;g->V[7]=v8;g->E=(int**)malloc(g->v_n*sizeof(int*));for(int i=0;i<g->v_n;i++){g->E[i]=(int*)malloc(g->v_n*sizeof(int));}for(int i=0;i<g->v_n;i++){for(int j=0;j<g->v_n;j++){g->E[i][j]=0;}}g->E[0][1]=1;g->E[1][2]=1;g->E[1][4]=1;g->E[1][5]=1;g->E[2][3]=1;g->E[2][6]=1;g->E[3][2]=1;g->E[3][7]=1;g->E[4][0]=1;g->E[4][5]=1;g->E[5][6]=1;g->E[6][5]=1;g->E[6][7]=1;g->E[7][7]=1;return g;}//矩阵转置,除了取反向边,其余全部复制pGraph transposeGraph(pGraph x){pGraph g = (pGraph)malloc(sizeof(Graph));g->v_n=x->v_n;g->TopoOrder=(int*)malloc(g->v_n*sizeof(int));g->V = (pVertex *)malloc(g->v_n*sizeof(Vertex));for(int i=0;i<g->v_n;i++){pVertex v=(pVertex)malloc(sizeof(Vertex));v->color=x->V[i]->color;v->group=x->V[i]->group;v->name=x->V[i]->name;v->f=x->V[i]->f;g->V[i]=v;}for(int i=0;i<g->v_n;i++){g->TopoOrder[i]=x->TopoOrder[i];}g->E=(int**)malloc(g->v_n*sizeof(int*));for(int i=0;i<g->v_n;i++){g->E[i]=(int*)malloc(g->v_n*sizeof(int));}for(int i=0;i<g->v_n;i++){for(int j=0;j<g->v_n;j++){if(x->E[i][j]==1)g->E[j][i]=1;elseg->E[j][i]=0;}}return g;}void dfsVisit(pGraph g,int v){g->V[v]->color=GRAY;for(int i=0;i<g->v_n;i++){if(g->E[v][i]==1){if(g->V[i]->color==WHITE)dfsVisit(g,i);}}g->V[v]->color=BLACK;g->V[v]->f=CNT;g->TopoOrder[CNT]=v;CNT++;}void dfs(pGraph g){for(int i=0;i<g->v_n;i++){g->V[i]->color=WHITE;}CNT=CNT_GROUP=0;for(int i=0;i<g->v_n;i++){if(g->V[i]->color==WHITE)dfsVisit(g,i);}}void dfsVisit2(pGraph g,int v){g->V[v]->color=GRAY;for(int i=0;i<g->v_n;i++){if(g->E[v][i]==1){if(g->V[i]->color==WHITE)dfsVisit2(g,i);}}g->V[v]->color=BLACK;g->V[v]->f=CNT;g->V[v]->group=CNT_GROUP;CNT++;}void dfs2(pGraph g){for(int i=0;i<g->v_n;i++){g->V[i]->color=WHITE;}CNT=CNT_GROUP=0;for(int i=g->v_n-1;i>=0;i--){int j=g->TopoOrder[i];if(g->V[j]->color==WHITE){dfsVisit2(g,j);CNT_GROUP++;}}}void printGroup(pGraph g){for(int i=0;i<g->v_n;i++){printf("%c:%d,",g->V[i]->name,g->V[i]->group);}printf("\n");}void printTopo(pGraph g){for(int i=g->v_n-1;i>=0;i--){int j=g->TopoOrder[i];printf("%c:%d,",g->V[j]->name,i);}printf("\n");}void printE(pGraph g){for(int i=0;i<g->v_n;i++){for(int j=0;j<g->v_n;j++){printf("%d ",g->E[i][j]);}printf("\n");}}//分两遍DFS,第一遍取得原图Topo序列,第二遍根据Topo序列遍历顶点,取得强连通分量//为什么两遍可以取得强连通分量,请参考http://blog.sina.com.cn/s/blog_4dff87120100r58c.htmlvoid main(){pGraph g=initGraph();dfs(g);//printE(g);printTopo(g);pGraph gt=transposeGraph(g);dfs2(gt);//printE(gt);printGroup(gt);getchar();}

原创粉丝点击