拓扑排序的应用
来源:互联网 发布:南昌市金域名都二手房 编辑:程序博客网 时间:2024/05/22 00:50
/*adjlist.h有向无环图的邻接表存储结构*/
#include<stdio.h>#include<stdlib.h>#include<string.h>#define MAX_VERTEX_NUM 10#define MAX_NAME 10typedef char VertexData[MAX_NAME];typedef struct ArcNode{int adjvex;int weight;struct ArcNode *nextarc;}ArcNode;typedef struct VertexNode{VertexData data;ArcNode *firstarc;}VertexNode;typedef struct{VertexNode vertex[MAX_VERTEX_NUM];int vertexnum,arcnum;}AdjList;void Visit(char *s){printf("%s",s);}int LocateVertex(AdjList *G,VertexData u){int i;for(i=0;i<G->vertexnum;i++)if(!strcmp(u,(*G).vertex[i].data))return i;return -1;}void CreateGraph(AdjList *G){int i;int head,tail;VertexData vh,vt;ArcNode *p=NULL,*pnew=NULL;printf("请输入有向无环图的顶点数,边数(以逗号隔开):");scanf("%d,%d",&G->vertexnum,&G->arcnum);for(i=0;i<G->vertexnum;i++){printf("请输入%d个顶点(工程事件): \n",i+1);scanf("%s",(*G).vertex[i].data);(*G).vertex[i].firstarc=NULL;}for(i=0;i<G->arcnum;i++){printf("输入第%d个活动的弧头: ",i+1);scanf("%s",vh);printf("输入第%d个活动的弧尾:",i+1);scanf("%s",vt);head=LocateVertex(G,vh);tail=LocateVertex(G,vt);pnew=(ArcNode *)malloc(sizeof(ArcNode));pnew->adjvex=head;pnew->nextarc=NULL;printf("请输入这个活动的时间: ");scanf("%d",&(pnew->weight));putchar('\n');p=(*G).vertex[tail].firstarc;if(p==NULL)(*G).vertex[tail].firstarc=pnew;else{while(p->nextarc!=NULL)p=p->nextarc;p->nextarc=pnew;}}}
/*stack.h栈的存储结构*/
#define MAX_STACK_NUM MAX_VERTEX_NUM+1typedef struct{int stack[MAX_STACK_NUM];int top;}Stack;void InitStack(Stack *S){S->top=-1;}bool StackEmpty(Stack *S){if(S->top<0)return true;elsereturn false;}bool IsFull(Stack *S){if(S->top>MAX_VERTEX_NUM)return true;elsereturn false;}bool Push(Stack *S,int in){S->top++;if(IsFull(S)){fprintf(stderr,"栈满");return false;}S->stack[S->top]=in;return true;}bool Pop(Stack *S,int *out){if(StackEmpty(S)){fprintf(stderr,"栈空\n");return false;}*out=S->stack[S->top--];return true;}
/*main.c驱动程序*/
#include"adjlist.h"#include"stack.h"int indegree[MAX_VERTEX_NUM];int ve[MAX_VERTEX_NUM]; //各顶点事件的最早发生时间int vl[MAX_VERTEX_NUM]; //各顶点事件的最迟发生时间void FindIndegree(AdjList *G){int i,k;ArcNode *p;for(i=0;i<G->vertexnum;i++)for(p=G->vertex[i].firstarc;p;p=p->nextarc){k=p->adjvex;indegree[k]++;}}bool TopologicalOrder(AdjList *G,Stack *T){int i,j,k;int count=0;//用来对输出的拓扑序列进行计数ArcNode *p=NULL;//用来将每次以出栈顶点为弧尾的弧删除的辅助指针Stack S;//S为0入度顶点栈memset(indegree,0,sizeof(indegree));memset(ve,0,sizeof(ve)); //初始化顶点事件 最早发生时间FindIndegree(G);InitStack(&S);/*接下来让所有入度为0的顶点入栈*/for(i=0;i<G->vertexnum;i++)if(!indegree[i])Push(&S,i);InitStack(T);printf("\n拓扑序列是: ");while(!StackEmpty(&S)){Pop(&S,&j);Push(T,j);++count; //j号顶点入T栈并计数printf("%s ",G->vertex[j].data);for(p=G->vertex[j].firstarc;p;p=p->nextarc) { k=p->adjvex; if(!(--indegree[k])) Push(&S,k); //若k顶点入度为0则入0度顶点栈S if(ve[j]+p->weight > ve[k]) ve[k]=ve[j]+p->weight;//这条if语句求以k为弧头的顶点的最早发生时间 }}if(count<G->vertexnum) //该有向图有回路return false;return true;}bool CriticalPath(AdjList *G){int i,j,k;int dut; //记录活动时间int ee,el; //ee代表活动的最早开始时间,el代表活动的最迟开始时间ArcNode *p;Stack T; //栈T是拓扑序列栈if(TopologicalOrder(G,&T))printf("\n工程能顺利完工\n");else{printf("\n工程无法顺利完工\n");return false;}for(i=0;i<G->vertexnum;i++)//初始化顶点事件 最迟发生时间vl[i]=ve[G->vertexnum-1];/*接下来按拓扑逆序求个顶点的vl值*/while(!StackEmpty(&T)){Pop(&T,&j);for(p=G->vertex[j].firstarc;p;p=p->nextarc){k=p->adjvex;dut=p->weight;if(vl[k] - dut < vl[j])vl[j]=vl[k] -dut;}} /*到此处为止已经求出了给个顶点的ve和vl值了最后要求关键活动只要 比较弧的ee和el值如果相等就代表该弧所代表的就是关键活动*/printf("该工程的关键活动是:\n");for(i=0;i<G->vertexnum;i++)for(p=G->vertex[i].firstarc;p;p=p->nextarc){k=p->adjvex;dut=p->weight;ee=ve[i];el=vl[k]-dut;if(ee==el)printf("\t从%s到%s所经时间\n",G->vertex[i].data,G->vertex[k].data);} return true;}int main(void){AdjList G;//freopen("text.txt","r",stdin);CreateGraph(&G);if(CriticalPath(&G))printf("最短工期为%d\n",ve[G.vertexnum-1]);//fclose(stdin);}
0 0
- 拓扑排序的应用
- 拓扑排序的应用(zoj3780)
- [poj3687]拓扑排序的应用
- 数据结构--拓扑排序的应用
- POJ4084拓扑排序--DFS的应用
- 图的拓扑排序及其应用
- 拓扑排序及其应用
- 拓扑排序应用
- hihoCoder - 1175 - 拓扑排序·二 (拓扑排序的应用)
- poj1094(拓扑排序应用)
- 图论--拓扑排序及其应用
- POJ-1094 -拓扑排序应用
- 拓扑排序简单应用poj2367
- POJ 3687 拓扑排序应用
- 拓扑排序应用 hdu 1285
- 拓扑排序模板及其应用
- POJ3687 Labeling Balls(拓扑排序的应用)
- 数据结构---->图的应用(拓扑排序,关键路径)
- Android APK加壳技术方案【1】
- RTP协议分析
- 技术网站
- NYOJ 198 数数
- Windows下部署基于Apache的SVN服务器
- 拓扑排序的应用
- 南阳-119-士兵杀敌(三)
- 妈妈 电子商务王闯
- jsp用javascript关于浏览器静止后退,刷新
- 【android,1】1.android的基本配置和布局
- 第17周项目2-体会函数参数传递(二)
- Android APK加壳技术方案【2】
- 计算Haar特征个数
- linux系统管理