论坛上的各位大神帮我看看这个图的关键路径是不是求错了,图有2个起始点为什么求出来的关键路径只从其中的一个起始点出发,是不是有问题?万分感谢!
程序代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_VER_NUM 13 #define MAX_ARC_NUM 19 typedef char VertexType[4]; struct ArcInfo { VertexType v1; VertexType v2; }; typedef struct ArcBox { int adjver; int weight; struct ArcBox *nextarc; }ArcBox; typedef struct VerBox { VertexType data; ArcBox *firstarc; }VerBox; typedef struct Graph { VerBox adjlist[MAX_VER_NUM]; int vernum; int arcnum; }Graph; typedef struct StackInfo { int data; struct StackInfo *next; }StackInfo; typedef struct Stack { StackInfo *ptop; StackInfo *pbottom; }Stack; typedef struct Path//存放关键路径 { char v1[4],v2[4]; int lenght; }PathNode; typedef struct EdgeInfo { char v1[4]; char v2[4]; int weight; }EdgeInfo; char VerData[][4]={"C1","C2","C3","C4","C5","C6","C7","C8","C9","C10","C11","C12","C13"}; EdgeInfo EdgeData[MAX_ARC_NUM]={{"C1","C3",7},{"C1","C12",4},{"C1","C2",5},{"C1","C4",3},{"C2","C3",2},{"C3","C5",2},{"C3","C7",3},{"C3","C8",5},{"C4","C5",6},{"C5","C7",2} ,{"C6","C8",5},{"C7","C13",8},{"C8","C13",3},{"C9","C11",2},{"C9","C10",1},{"C9","C12",4},{"C10","C12",3},{"C11","C6",4},{"C12","C13",9}}; Stack T;//存放拓扑排序结果求ltv使用 char result[MAX_VER_NUM][4];//存放拓扑结果用于输出结果使用 int Indegree[MAX_VER_NUM]={0},Visited[MAX_VER_NUM]; int *etv,*ltv; int LocateVer(Graph G,VertexType v) { int i; for(i=0;i<G.vernum;i++) { if(strcmp(v,G.adjlist[i].data)==0) { return i; } } return -1; } void CreateGraph(Graph **G) { VertexType v1,v2; //char c; int i,j,k,l,w; ArcBox *pnew; //FILE *fp; (*G)=new Graph; (*G)->arcnum=MAX_ARC_NUM; (*G)->vernum=MAX_VER_NUM; for(i=0;i<(*G)->vernum;i++) { strcpy((*G)->adjlist[i].data,VerData[i]); (*G)->adjlist[i].firstarc=NULL; } //fp=fopen("data.txt","r"); //if(fp==NULL) printf("文件打开失败!"),exit(0); for(k=0;k<(*G)->arcnum;k++) { /*c=fgetc(fp); l=0; while(c!=' ') { v1[l++]=c; c=fgetc(fp); } v1[l]='\0'; c=fgetc(fp); l=0; while(c!=' ') { v2[l++]=c; c=fgetc(fp); } v2[l]='\0'; fscanf(fp,"%d",&w); fgetc(fp);*/ strcpy(v1,EdgeData[k].v1); strcpy(v2,EdgeData[k].v2); w=EdgeData[k].weight; i=LocateVer(**G,v1); j=LocateVer(**G,v2); if(i>=0&&j>=0) { pnew=new ArcBox; pnew->adjver=j; pnew->weight=w; pnew->nextarc=(*G)->adjlist[i].firstarc; (*G)->adjlist[i].firstarc=pnew; } } return; } void FindInDegree(Graph G)//求各顶点的入度 { int i; ArcBox *p; for(i=0;i<G.vernum;i++) { p=G.adjlist[i].firstarc; while(p!=NULL) { Indegree[p->adjver]++; p=p->nextarc; } } return; } void ShowAdjList(Graph G)//查看邻接表 { int i; ArcBox *p; for(i=0;i<G.vernum;i++) { p=G.adjlist[i].firstarc; printf("[%d|%s]",i,G.adjlist[i].data); while(p!=NULL) { printf("->[%d|%s|%d]",p->adjver,G.adjlist[p->adjver].data,p->weight); p=p->nextarc; } printf("\n"); } } void InitStack(Stack *S,Stack *T) { S->pbottom=S->ptop=(StackInfo *)malloc(1*sizeof(StackInfo)); S->ptop->next=NULL; T->pbottom=T->ptop=(StackInfo *)malloc(1*sizeof(StackInfo)); T->ptop->next=NULL; return; } void Push(Stack *S,int i) { StackInfo *pnew; pnew=(StackInfo *)malloc(1*sizeof(StackInfo)); pnew->data=i; pnew->next=S->ptop; S->ptop=pnew; return; } int EmptyStack(Stack S) { if(S.pbottom==S.ptop) { return 1; } else { return 0; } } void Pop(Stack *S,int *i) { StackInfo *p; p=S->ptop; S->ptop=p->next; *i=p->data; free(p); return; } bool TopoSort(Graph *G) { int i,k,count=0,l=0; Stack S; ArcBox *p; etv=(int *)malloc(G->vernum*sizeof(int)); ltv=(int *)malloc(G->vernum*sizeof(int)); InitStack(&S,&T); FindInDegree(*G); for(i=0;i<G->vernum;i++) { etv[i]=0; if(Indegree[i]==0) { Push(&S,i); } } while(EmptyStack(S)==0) { Pop(&S,&i);Push(&T,i);count++; strcpy(result[l++],G->adjlist[i].data); printf("%-3s ",G->adjlist[i].data); for(p=G->adjlist[i].firstarc;p!=NULL;p=p->nextarc) { k=p->adjver; if(--Indegree[k] ==0) { Push(&S,k); } if(etv[i]+p->weight>etv[k]) { etv[k]=etv[i]+p->weight; } } } printf("\n etv:"); if(count<G->vernum) { printf("该图有环无法进行拓扑排序!\n"); return false; } else { for(i=0;i<G->vernum;i++)//输出etv { l=LocateVer(*G,result[i]); printf("%-3d ",etv[l]); } printf("\n"); return true; } } int FirstAdjVer(Graph *G,int v) { int n=-1; ArcBox *p; p=G->adjlist[v].firstarc; if(p!=NULL) { n=p->adjver; } return n; } int NextAdjVer(Graph *G,int v,int w) { int n=-1; ArcBox *p; p=G->adjlist[v].firstarc; while(p!=NULL) { if(p->adjver==w && p->nextarc!=NULL) { n=p->nextarc->adjver; break; } p=p->nextarc; } return n; } void DFS(Graph *G,int v,int *flag) { int w; Visited[v]=1; for(w=FirstAdjVer(G,v);w>=0;w=NextAdjVer(G,v,w)) { if(Visited[w]==0 &&*flag==1) { DFS(G,w,flag); Visited[w]=0; } else { *flag=0; break; } } } int IsDAG(Graph *G) { int i,v,flag=1; for(i=0;i<G->vernum;i++) { Visited[i]=0; } for(v=0;v<G->vernum;v++) { if(Visited[v]==0 && flag==1) { DFS(G,v,&flag); Visited[v]=0; } } return flag; } void TSDFS(Graph *G,int v) { int w; Visited[v]=1; for(w=FirstAdjVer(G,v);w>=0;w=NextAdjVer(G,v,w)) { if(Visited[w]==0) { TSDFS(G,w); } } printf("%s ",G->adjlist[v].data); return; } void TopoSort_DFS(Graph *G) { int i,v; if(IsDAG(G)) { for(i=0;i<G->vernum;i++) { Visited[i]=0; } for(v=0;v<G->vernum;v++) { if(Visited[v]==0) { TSDFS(G,v); } } } else printf("该图有环无法拓朴排序!\n"); } void CriticalPath(Graph *G) { int i,k,l=0; ArcBox *p; int ete[MAX_ARC_NUM],lte[MAX_ARC_NUM]; PathNode path[MAX_ARC_NUM]; for(i=0;i<G->vernum;i++) { ltv[i]=etv[G->vernum-1]; } while(EmptyStack(T)==0) { Pop(&T,&i); for(p=G->adjlist[i].firstarc;p!=NULL;p=p->nextarc) { k=p->adjver; if(ltv[i]>ltv[k]-p->weight) { ltv[i]=ltv[k]-p->weight; } } } FindInDegree(*G); for(i=0;i<G->vernum;i++)//起始点ltv置为0 { if(Indegree[i]==0) { ltv[i]=0; } } printf(" ltv:"); for(i=0;i<G->vernum;i++)//输出ltv { k=LocateVer(*G,result[i]); printf("%-3d ",ltv[k]); } printf("\n"); k=0; printf("\n 弧:"); for(i=0;i<G->arcnum;i++) { printf("%c%-2d ",'a',i+1); } printf("\bete:"); for(i=0;i<G->vernum;i++)//对ete求值 { for(p=G->adjlist[i].firstarc;p!=NULL;p=p->nextarc) { ete[k]=etv[i]; lte[k]=ltv[p->adjver]-p->weight; if(ete[k]==lte[k]) { strcpy(path[l].v1,G->adjlist[i].data); strcpy(path[l].v2,G->adjlist[p->adjver].data); path[l].lenght=p->weight; l++; } k++; printf("%-3d ",ete[k-1]); } } printf("\blte:"); for(i=0;i<G->arcnum;i++)//输了lte的值 { printf("%-3d ",lte[i]); } printf("\n关键路径为:\n"); for(i=0;i<l;i++)//输出关键路径 { printf("<%-3s--%-3s> %d\n",path[i].v1,path[i].v2,path[i].lenght); } } int main() { Graph *G; CreateGraph(&G); printf("邻接表信息:\n"); ShowAdjList(*G); printf("拓朴排序结果:"); TopoSort(G); //printf("\n深度优先遍历逆向拓扑排序:"); //TopoSort_DFS(G); //putchar(10); CriticalPath(G); return 0; }