1、ACM经典模版之拓扑排序拓扑排序:/基础邻接矩阵的数据结构定义:typedef struct My_Graph bool *matrix; /图的邻接矩阵 infro *data; /点的信息 int points; /点的个数 int sides; /边的个数; /对邻接矩阵的点求入度 void FindInDegree( My_Graph &T ,int *indegree ) int i,j; for( i = 0 ; i T.points ;i+) indegreei=0; for( i =0 ; i T.points ; i+ ) for( j =0 ; j T.points ; j
2、+ ) if( T.matrixji = 1 ) indegreei+; /for j /for i /FindInDegree /邻接矩阵的建立: void InitiGraph( My_Graph &T ) cout 请输入该矩阵的点的个数和边的个数: T.points T.sides ; while( T.points 0 ) cout 数据不符合规范!请重新输入! T.points; cin T.sides; /T.ponits int i,j; /为邻接矩阵分配合适大小的空间 T.matrix = new bool *T.points+1; for( i = 0 ; i T.poin
3、ts ; i+ ) T.matrixi = new bool T.points+1; /输入 for( i = 0 ; i T.points ; i+ ) for( j = 0 ; j T.matrixij; T.data = new infroT.points+1; cout 请输入 T.points 个点的信息: endl; for( i = 0 ; i T.datai; /InitiGraph /输出拓扑排序的结果 void TopologicalSort( My_Graph &T ) int i; int v; int *indgree; indgree = new intT.poin
4、ts+1; SqStack S; InitStack(S); FindInDegree(T,indgree); for( i =0 ; i T.points ; i+ ) if( indgreei = 0 ) Push(S,i); while( !StackEmpty(S) ) Pop(S,i); cout T.datai ; for( v = 0 ; v T.points ; v+ ) if( T.matrixiv != 0 ) indgreev-; if( indgreev = 0 ) Push(S,v); /if /for v /while /TopologicalSort;图的操作:/
5、基础邻接矩阵的数据结构定义:typedef struct My_Graph bool *matrix; /图的邻接矩阵 int points; /点的个数 int sides; /边的个数; bool StackEmpty( SqStack S ) if ( S.base = S.top ) return false; else return true; /StackEmpty /* /寻找第一个邻接的位置 int FirstAdjVex( My_Graph &T , int i ) int v; for( v = 0 ; v T.points ; v+ ) if( T.matrixiv =
6、1 ) return v; return -1; /FirstAdjVex /* /寻找下一个邻接的位置 int NextAdjVex( My_Graph &T , int i , int w ) int v; for( v = w + 1; v =0 ; w = NextAdjVex(T,i,w) ) /cout w = 0 ) if ( visitedu = false ) printf( %3c , A+u ); visitedu = true; Push(S,u); u = FirstAdjVex(T,u); else GetTop(S,v); u = NextAdjVex(T,v,u
7、); /while Pop(S,i); /while /if /DFS_Nonrecursive / DFS_递归_遍历 void DFS_Recurrence_Traverse( My_Graph &T ) int i; bool *visited; visited = new boolT.points+2; for( i = 0 ; i T.points ; i+ ) visitedi = false; for( i = 0 ; i T.points ; i+ ) if( visitedi = false ) DFS_Recurrence( T , i , visited); / for
8、i /DFS_Recurrence_Traverse /DFS_非递归_遍历 void DFS_Nonrecursive_Traverse( My_Graph &T ) SqStack S; InitiStack(S); int i; bool *visited; visited = new boolT.points + 2; for( i = 0 ; i T.points ; i+ ) visitedi = false; for( i = 0 ; i T.points ; i+ ) if( visitedi = false ) DFS_Nonrecursive(T,S,i,visited);
9、 /for i /DFS_Nonrecursive_Traverse /BFS_遍历 void BFS_Traverse( My_Graph &T ) int i; sqQueue Q; bool *visited; visited = new boolT.points+2; IninQueue(Q); for( i =0 ; i T.points+1 ; i+ ) visitedi = false; int w,u; for( i = 0; i = 0 ; w = NextAdjVex(T,u,w) ) if( visitedw = false ) printf(%3c,A+w); visi
10、tedw = true; EnQueue(Q,w); /for w /while not null / if visited /for i /BFS_Traverse/关键路径 求VE的函数,并且保存VE点,返回一个拓扑序列,保存在T中 int TopologicalOder( My_Graph &G, SqStack &T , int *ve ) int cout=0; int i,j,k,v; int *indegree; indegree = new intG.points+1; SqStack S; InitStack(S); for( i =0 ; i G.points ;i+ )
11、/对VE和INDEGREE数组进行初始化 indegreei= vei = 0 ; FindInDegree(G,indegree); for( i =0 ; i G.points ; i+ ) /把入度为0的点,压入栈中 if( indegreei = 0 ) Push(S,i); while ( !StackEmpty(S) ) /栈不为空,表示栈中还存在的有入度为0的点 Pop(S,j); Push(T,j); /压入一个拓扑序列中 cout+; for( v = 0 ; v vev ) /动态转移,找到(最大)最早发生时间 vev = vej+G.matrixjv; /if G.mat
12、rixjv != 0 /for j /while if( cout G.points ) return 0; else return 1; /TopologicalOder /求关键路径的主函数 void GriticalPath( My_Graph M ) int i,j,k,v; int *ve,*vl,e,l; ve = new intM.points+1; vl = new intM.points+1; SqStack T; InitStack(T); if( !TopologicalOder(M,T,ve) ) cout 图中有环! endl; exit(0); for( i =0
13、; i M.points ; i+ ) /初始化赋值为:最大的值,即是出度为0点 vli = veM.points-1; while( !StackEmpty(T) ) for( Pop(T,j), v= 0; v M.points ; v+ ) if( M.matrixjv != 0 ) if( vlv - M.matrixjv vlj ) /动态转移,寻找最迟发生的点(即是逆序求值最小的点) vlj = vlv - M.matrixjv; /if /for v /while for( i =0 ; i M.points ; i+ ) for( v = 0 ; v M.points ; v+
14、 ) if( M.matrixiv != 0 ) /寻找最短路径(当活动发生时间和开始时间相当即为最短路径的点) e = vei; l = vlv-M.matrixiv; if( e = l) cout 点 M.datai 到点 M.datav 是关键路径,长度为 M.matrixiv endl; cout endl; /for v /for /GriticalPath; /用于将字符加入到字符串中 void add( char p ,int i, int &len ,int start) if( len = 0 ) /设置起点为,预订的点(A) plen+ = A+start; plen =
15、 char(A+i); /记录 plen+1 = 0; /设置结束符 len+; /长度加1 /add /将字符串清理 void empty( char p ) /将字符清理,消除乱码 memset(p,0,sizeof(p); /empty /复制路径函数 void copy( char a, char b ) strcpy(a,b); /copy public: /邻接矩阵的建立: void InitiGraph( My_Graph &T ) cout 请输入该矩阵的点的个数和边的个数: T.points T.sides ; while( T.points 0 ) cout 数据不符合规范
16、!请重新输入! T.points; cin T.sides; /T.ponits int i,j; /为邻接矩阵分配合适大小的空间 T.matrix = new int *T.points+1; for( i = 0 ; i T.points ; i+ ) T.matrixi = new int T.points+1; /输入 for( i = 0 ; i T.points ; i+ ) for( j = 0 ; j T.matrixij; T.data = new inforT.points+1; cout 请输入 T.points 个点的信息: endl; for( i = 0 ; i T
17、.datai; /InitiGraph /老师所讲的方法,利用字符串保存路径 void ShorterstPath1_DIJ( const My_Graph M ,int start, Elem *D, char *p ) const int MAX=999999; int i,j,k; int min; bool *S; S = new boolM.points+1; int *len; len = new intM.points; /初始化 for( i =0 ; i M.points ; i+ ) leni = 0; /将每一个点的路径初始为空 Si = false; /每一个点为设置没
18、有加入到集合S中 Di = M.matrixstarti; /保存初始的路径长度 if( Di MAX ) pi0 = A+start; leni+; add(pi,i,leni,start); else empty(pi); /for i Sstart = 1; /将起点加入到集合S中 int pos; /最短路径的位置 for( i = 1 ; i M.points ; i+ ) min = MAX; pos = 0; for( j = 0 ; j Dj ) min = Dj; pos = j; Spos = true; /加入到S集合中 for( k = 0 ; k M.matrixpo
19、sk+min ) Dk = M.matrixposk+min; /更新路径长度 copy(pk,ppos); /保存和设置路径 lenk = strlen(ppos); add(pk,k,lenk,start); /if /for k /for i /ShorterstPath1_DIJ /*格雷码模拟(九连环模拟)/给一串01序列,按九连环方法(1为环)取下所有环,求最少步数(POJ 1090)#includeusing namespace std;int a1001,b1001;int ans200,flag200;int main() int n; cinn; /freopen(car.in,r,stdin); /freopen(car.out,w,stdout); memset(a,0,sizeof(a); memset(b,0,sizeof(b); memset(ans,0,sizeof(ans); memset(flag,0,sizeof(flag); int i,j; for(i=0;iai; if(ai)j=i; for(i=0;i=j;+i)bi=aj-i; for(i=1;i=j;+i)bi=bi-1bi; int len1,len2,t; flag
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1