p=p->next;
j++;
}
if(!
p)//i值大于表长+1
returnERROR;
s->next=p->next;
p->next=s;
}
returnOK;
}
/***********************************************************************************/
voidCreategraph(Algraph*G){
inti,j,k,w;
VertextypeV1,V2;
Arcnode*e;
printf("请输入图的顶点数,边数(以空格作为间隔):
\n");
scanf("%d%d",&G->vexnum,&G->arcnum);
printf("请输入%d个顶点的值(小于%d个字符):
\n",G->vexnum,Maxname);
for(i=0;ivexnum;++i){//构造顶点向量并初始化
scanf("%s",G->vertices[i].data);
G->vertices[i].firstarc=NULL;
}
printf("请输入%d条弧的弧尾,弧头和权值(以空格作为间隔):
\n",G->arcnum);
for(k=0;karcnum;++k){
scanf("%s%s%d",V1,V2,&w);
i=Locatevex(*G,V1);
j=Locatevex(*G,V2);
e=(Arcnode*)malloc(sizeof(structArcnode));////修正:
为每条弧分配内存,插入链表
e->weight=w;
e->adjvex=j;
e->nextarc=NULL;
Listinsert(&(G->vertices[i].firstarc),1,e);//插在第j个元素的表头
}
}
/***********************************************************************************/
voidDisplay(Algraph*G){
inti;
Linklistp;
printf("%d个顶点:
",G->vexnum);
for(i=0;ivexnum;++i)
printf("%s",G->vertices[i].data);
printf("\n%d\n条弧:
",G->arcnum);
for(i=0;ivexnum;++i){
p=G->vertices[i].firstarc;
while(p){
printf("%5s%5s%5d",G->vertices[i].data,G->vertices[p->adjvex].data,p->weight);///////////
p=p->nextarc;//////////////////////
}
printf("\n");
}
}
/*******************************************************************************************/
voidFindindegree(Algraph*G,intindegree[]){
inti;
Arcnode*p;
for(i=0;ivexnum;++i)
indegree[i]=0;
for(i=0;ivexnum;++i){
p=G->vertices[i].firstarc;
while(p){
indegree[p->adjvex]++;
p=p->nextarc;
}
}
}
/***********************************************************************************************/
voidInitstack(Sqstack*S){
S->base=(Selemtype*)malloc(Sinitsize*sizeof(Selemtype));
if(!
(S->base))
exit(OVERFLOW);
S->top=S->base;
S->stacksize=Sinitsize;
}
StatusStackempty(Sqstack*S){
if(S->top==S->base)
returnTRUE;
elsereturnERROR;
}
voidPush(Sqstack*S,Selemtypee){
if(S->top-S->base>=S->stacksize){
S->base=(Selemtype*)realloc(S->base,(S->stacksize+Sincrement)*sizeof(Selemtype));
if(!
(S->base))
exit(OVERFLOW);
S->top=S->base+S->stacksize;
S->stacksize+=Sincrement;
}
*(S->top)++=e;
}
StatusPop(Sqstack*S,Selemtype*e){
if(S->top==S->base)
returnERROR;
*e=*(--S->top);
returnOK;
}
/*************************************************************************************************/
StatusTopologicalOrder(Algraph*G,Sqstack*T){
intCount=0;
intN=0;
inti,k,count=0;
intindegree[Maxvexnum];
SqstackS;
Arcnode*p;
Findindegree(G,indegree);
Initstack(&S);
for(i=0;ivexnum;++i)
{if(indegree[i]==0)
{Push(&S,i);//入度为零者进栈
Count++;}
if(G->vertices[i].firstarc==NULL)
N++;}
printf("\n");
if(Count>1)
{printf("图中有%d个源点,不能找出关键路径!
!
!
\n",Count);return0;}
elseif(N>1)
{printf("图中有%d个汇点,不能找出关键路径!
!
!
\n",N);return0;}
printf("\n");
printf("拓扑序列:
");
Initstack(T);
for(i=0;ivexnum;++i)///////////
ve[i]=0;
while(!
Stackempty(&S)){
Pop(&S,&i);
printf("%s",G->vertices[i].data);
Push(T,i);
++count;//对输出顶点计数
for(p=G->vertices[i].firstarc;p;p=p->nextarc){
k=p->adjvex;//对i号顶点的每个邻接点的入度减一
if(--indegree[k]==0)
Push(&S,k);
if(ve[i]+p->weight>ve[k])
ve[k]=ve[i]+p->weight;
}//for
}//while
if(countvexnum){
printf("此有向网有回路\n");
return0;
}
elsereturn1;
}//TopologicalOrder
StatusCriticalPath(Algraph*G){
intsum=0;
intvl[Maxvexnum];
SqstackT;
inti,j,k,ee,el,dut;
Arcnode*p;
if(!
TopologicalOrder(G,&T))
return0;
j=ve[0];
for(i=0;ivexnum;i++)
if(ve[i]>j)
j=ve[i];
for(i=0;ivexnum;i++)
vl[i]=j;
while(!
Stackempty(&T))
for(Pop(&T,&j),p=G->vertices[j].firstarc;p;p=p->nextarc){
k=p->adjvex;
dut=p->weight;
if(vl[k]-dutvl[j]=vl[k]-dut;
}//for
printf("\nive[i]vl[i]\n");
for(i=0;ivexnum;++i){
printf("%d%d%5d",i,ve[i],vl[i]);
if(ve[i]==vl[i])
printf("关键路径经过的顶点");
printf("\n");
}
printf("jk权值eeel\n");
for(j=0;jvexnum;++j)//求ee,el和关键活动
for(p=G->vertices[j].firstarc;p;p=p->nextarc){
k=p->adjvex;
dut=p->weight;
ee=ve[j];
el=vl[k]-dut;
printf("%s-->%s%3d%5d%5d",G->vertices[j].data,G->vertices[k].data,dut,ee,el);
if(ee==el)
printf("关键活动");
printf("\n");
}//for
j--;
printf("路径长度为:
%d",ve[j]);
printf("\n");
return1;
}
voidmain()
{
Algraphh;
Creategraph(&h);
Display(&h);
CriticalPath(&h);
}