图的关键路径

 
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_VERTEX_NUM 20
#define OVERFLOW 0
#define OK 1
#define TRUE 1  
#define FALSE 0
#include<stack>
#define MAX 10000 
using namespace std;
typedef  int   Status  ;
typedef  char VertexType;
typedef  int  QElemType;
typedef struct ArcNode
{
     int adjvex;              			  //邻接点域,存储该邻点顶点对应的下标
     struct ArcNode *nextarc;			 //邻节点
     int weight;    					//权值
}ArcNode;
/*邻接表结构*/
typedef struct VNode
{ 
     VertexType data;	   			//顶点对应的值
     ArcNode  *firstarc;            //边表头指针指向邻顶点
}VNode,AdjList[MAX_VERTEX_NUM];

typedef struct
{
     AdjList  vertices;  
     int vexnum,arcnum;			    //顶点数,边数
}ALGraph;

void CreateALGraph(ALGraph *G)    //构建图
{
     ArcNode *p;
     int i,j,k,w;
     printf("输入顶点与边的数目:\n");
     scanf("%d%d",&G->vexnum,&G->arcnum);
     getchar();
     printf("输入顶点值:\n");
    for(i=1;i<=G->vexnum;i++)
    {
          
          scanf("%c",&G->vertices[i].data);
          getchar();
          G->vertices[i].firstarc=NULL;
    }
    //建立边表
    printf("输入邻接表对应的下标以及权值:\n");
    for(k=1;k<=G->arcnum;k++)
    {
          scanf("%d%d%d",&i,&j,&w);   //边对应的两个顶点下标并将俩顶点联系起来
          p = (ArcNode *)malloc(sizeof(ArcNode));
          p->adjvex = j;
          p->weight = w; 
          p->nextarc = G->vertices[i].firstarc;
          G->vertices[i].firstarc = p;
    }
}
 
void FindIndgree(ALGraph G,int Indegree[MAX]){
    memset(Indegree,0,sizeof(Indegree));
	ArcNode *p;
	for(int i = 1;i<=G.vexnum;i++){
        p = G.vertices[i].firstarc;  
        while(p)  
        {  
            Indegree[p->adjvex]++; 
            p = p->nextarc; 	 
        }  
    }     
}
int flag = 0;  //全局变量为逆拓扑排序的各顶点置最长路径 
/*先拓扑排好以及将对应的最长路径确定好*/
stack<int> T;
Status  TopologicalSort(ALGraph  G)  //引入T栈,将s栈中的零入度元素依次压入,目的:寻找路径时先从s
                                                //中最后入栈的开始,往前推判断是否为关键路径 
{ 

   stack<int> s;
   ArcNode *p;
   int count = 0;
   int Indegree[MAX];
   int ve[MAX];               //寻找路径的最长 
   FindIndgree(G,Indegree);
   for(int i = 1;i<=G.vexnum;i++){
   	    if(!Indegree[i]){
   	   	    s.push(i);  
		}
    }
    for(int i = 1;i<=G.vexnum;i++) {
    	    ve[i] = 0;             //初始化 
	}
    while(!s.empty()){
   	    int item = s.top();
   	    T.push(item);  
		s.pop();
   	    count++; 
   	    for(p=G.vertices[item].firstarc;p;p=p->nextarc){
   	        int k = p->adjvex;
			if(!(--Indegree[k]))  	s.push(k);     //入度为零,入栈 
			if(ve[item]+p->weight>ve[k])     ve[k] = ve[item]+p->weight; //如果前一个顶点(item)数组所含有的权值加上正在访问的p指向的权值相加 
			                                                            //与p的数组(k)所含的权值比较(向前推寻找最长路径) 
		}
    }
        flag  =  ve[G.vexnum];          
        if(count<G.vexnum)           //有环退出 
            return false;
        else
            return OK;
         
}
 
void  CriticalPath(ALGraph  &G)
{    
  
    ArcNode  *p;  
    if(!TopologicalSort(G))  exit(0) ;
    int ve2[MAX] = {0};    
    for(int i = 1;i<=G.vexnum;i++){
     	ve2[i] = flag;             //逆拓扑排序,将其各顶点元素赋最长路径 
	}
	 
	while(!T.empty()){
	    int k = T.top();	
		T.pop();
		for(p = G.vertices[k].firstarc;p;p = p->nextarc){   //反向求各顶点数组的权值(寻求各顶点数组权值最小) 
			int j = p->adjvex;        
			int num = p->weight;            
			if(ve2[j]-num<ve2[k])    ve2[k] = ve2[j]-num;
		}
			 
	 
//	    for(int i=1;i<=G.vexnum;i++)   
//        {
//            for(p=G.vertices[i].firstarc;p;p=p->nextarc)
//            {   
//                    int t = p->adjvex;
//                    int ete = ve2[i];
//                    int lte = ve2[t]-p->weight;
//                    if(ete==lte)    //如果符合TopologicalSort函数寻求最长路径确定的各个阶段则可输出该阶段的两顶点与对应的权值 
//                       printf("%c->%c,length:%d\n",G.vertices[i].data,G.vertices[t].data,p->weight);
//            }
//        }		
	}
	for(int i=1;i<=G.vexnum;)   
        {
            for(p=G.vertices[i].firstarc;p;p=p->nextarc)
            {       
                    int t = p->adjvex;                   
                    int lte = ve2[t]-p->weight;
                    //printf("%d***%d***%d",lte,t,ve2[t]) ;
					int ete = ve2[i];
                    if(ete==lte)    //如果符合TopologicalSort函数寻求最长路径确定的各个阶段则可输出该阶段的两顶点与对应的权值
					{
						printf("%c->%c,length:%d\n",G.vertices[i].data,G.vertices[t].data,p->weight);
					    i = t;  //如果此t顶点信息符合路径则直接跳到与这条t路径相关的路径上来探索。 
					}
                                                            
            }
           
        }		
}
int main(){
	ALGraph G;
	CreateALGraph(&G);
	stack<int> T;
    TopologicalSort(G);
    printf("关键路径为:\n"); 
	CriticalPath(G);
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值