拓扑排序 (c++)

 实验题目(共5题, 第2题)

标题: 拓扑排序
时 限: 2000 ms
内存限制: 5000 K
总时限: 6000 ms
描述: 以邻接矩阵给出一张以整数为结点的有向图,其中0表示不是相邻结点,1表示两个结点相连且由当前结点为初始点。利用拓扑排序判断图中是否有环,若有输出YES没有输出NO
输入:
结点数
邻接矩阵
输出:
YES/NO
输入样例:
3
0 1 0
1 0 1
1 0 0
输出样例: YES
提示:  
来源: 教材P180-182
View Code
  1 #include <stdio.h>
2 #include <stdlib.h>
3 #define STACK_INIT_SIZE 100
4 #define STACKINCREMENT 10
5
6 #define MAX 20
7 typedef int VertexType;
8 typedef struct ArcNode//表结点
9 {
10 int adjvex;//弧所指向的顶点的位置
11 struct ArcNode *nextarc;
12 }ArcNode;
13 typedef struct VNode//头结点
14 {
15 VertexType data;//顶点信息
16 ArcNode *firstarc;//指向第一条依附该弧的顶点指针
17 }VNode,*AdjList;
18 typedef struct
19 {
20 AdjList vertices;
21 int vexnum;//图的**当前**顶点数
22 }ALGraph;
23 typedef struct//栈的定义
24 {
25 int *base;
26 int *top;
27 int stacksize;
28 }SqStack;
29 /////////栈的操作函数定义
30 void initialStack(SqStack *s)
31 {
32 s->base=(int *)malloc(STACK_INIT_SIZE*sizeof(int));
33 if(!s->base) exit(0);
34 s->top=s->base;
35 s->stacksize=STACK_INIT_SIZE;
36 }
37 void Push(SqStack *s,int e)
38 {
39 if(s->top-s->base>=s->stacksize)
40 {
41 s->base=(int *)realloc(s->base,(STACK_INIT_SIZE+STACKINCREMENT)*sizeof(int));
42 if(!s->base) exit(0);
43 s->top=s->base+s->stacksize;
44 s->stacksize+=STACKINCREMENT;
45 }
46 *(s->top)++=e;
47 }
48 void Pop(SqStack *s,int *e)
49 {
50 if(s->top==s->base) exit(0);
51 *e=*--(s->top);
52 }
53 void GetTop(SqStack *s,int *e)
54 {
55 if(s->top==s->base) exit(0);
56 *e=*(s->top-1);
57 }
58 int StackEmpty(SqStack *s)
59 {
60 if(s->base==s->top)
61 return(1);
62 else
63 return(0);
64 }
65 /////创建图的邻接矩阵
66 void CreatAjacentMatrix(int *array,int n)//创建邻接矩矩阵(n行n列)
67 {
68 int a;
69 int i,j;
70 for(i=0;i<n;i++)
71 for(j=0;j<n;j++)
72 {
73 scanf("%d",&a);
74 *(array+i*n+j)=a;
75 }
76 }
77 ////将邻接矩阵导出为图的邻接表形式
78 void CreatAdjList(int *array,int n,ALGraph *G)
79 {
80 int i,j;
81 ArcNode *p;//表结点
82 G->vexnum=n;//初始化顶点数
83 G->vertices=(VNode *)malloc((n+1)*sizeof(VNode));//头结点数组,开辟n+1长度的数组空间
84 for(i=1;i<=n;i++)//初始化头结点数组
85 {
86 G->vertices[i].data=i;
87 G->vertices[i].firstarc=NULL;
88 }
89 //////////
90 for(i=0;i<n;i++)
91 for(j=0;j<n;j++)
92 {
93 if(*(array+i*n+j)==1)
94 {
95 p=(ArcNode *)malloc(sizeof(ArcNode));
96 p->adjvex=j+1;
97 p->nextarc=G->vertices[i+1].firstarc;
98 G->vertices[i+1].firstarc=p;
99 }
100 }
101 }
102
103 void FindInDegree(ALGraph G,int *indegree)//对顶点求入度
104 {
105 int i,j;
106 ArcNode *p;
107 for(i=1;i<=G.vexnum;i++)
108 indegree[i]=0;//indispensable
109 for(i=1;i<=G.vexnum;i++)//对每个结点跑完整个邻接表
110 for(j=1;j<=G.vexnum;j++)
111 for(p=G.vertices[j].firstarc;p;p=p->nextarc)
112 if(G.vertices[i].data==p->adjvex)//==
113 indegree[i]++;
114 }
115
116 /////////拓扑排序算法
117 int TopologicalSort(ALGraph G)
118 {
119 //有向图采用邻接表存储结构
120 //若G无回路,则flag=0,输出G的顶点的一个拓扑序列,否则给出该有向图有回路的提示.
121 int i,count,k;
122 int *indegree=(int *)malloc((G.vexnum+1)*sizeof(int));
123 SqStack S;
124 ArcNode *p;
125 FindInDegree(G,indegree);//对顶点求入度indegree[G.vexnum]
126 initialStack(&S);//为避免重复检测入度为0的顶点,可另设一栈暂存放所有入度为0的顶点
127 for(i=1;i<=G.vexnum;i++)
128 if(!indegree[i])
129 Push(&S,i);//0入度点进栈
130 count=0;//对输出顶点计数,作为判断是否有回路的根据
131 while(!StackEmpty(&S))
132 {
133 Pop(&S,&i);
134 count++;
135 for(p=G.vertices[i].firstarc;p;p=p->nextarc)
136 {
137 k=p->adjvex;//表结点的数据域,即对i号顶点的每个邻接点的入度减1
138 if(!(--indegree[k]))//若入度减少为0,则入栈
139 Push(&S,k);
140 }
141 }
142 if(count<G.vexnum)//该有向图有回路
143 return 0;
144 else
145 return 1;
146 }
147 int main()
148 {
149 int n;
150 int *A;
151 ALGraph G;
152 scanf("%d",&n);
153 A=(int *)malloc(n*n*sizeof(int));
154 CreatAjacentMatrix(A,n);
155 CreatAdjList(A,n,&G);
156 if(TopologicalSort(G))
157 printf("NO");
158 else
159 printf("YES");
160 }
posted @ 2011-05-24 17:49  itbird  Views(2420)  Comments(1Edit  收藏  举报