图的C++关键路径代码

 #include using namespace std;//*****stack.h以下是栈的实现#define STACK_INIT_SIZE 100#define STACKINCREMENT 10typedef int Status;templateclass stack{public: void InitStack(); void DestroyStack(); void Clea
摘要由CSDN通过智能技术生成

 

#include <iostream>
using namespace std;
//*****stack.h以下是栈的实现
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef int Status;
template<class QElemType>
class stack
{
public:
 void InitStack();
 void DestroyStack();
 void ClearStack();
 Status StackEmpty();
 Status StackLength();
 void GetTop(QElemType & e);
 void Push(QElemType e);
 void Pop(QElemType & e);
private:
 struct SqStack{
  QElemType *base;
  QElemType *top;
  int stacksize;
 }S;
};
//******stack.cpp------
template<class QElemType>
void stack<QElemType>::InitStack()
{
 S.base = (QElemType *)malloc(STACK_INIT_SIZE * sizeof(QElemType));
 if(!S.base) exit(0);
 S.top = S.base;
 S.stacksize = STACK_INIT_SIZE;
}
template <class QElemType>
void stack<QElemType>::DestroyStack()
{
 free(S.base);
}
template <class QElemType>
void stack<QElemType>::ClearStack()
{
 S.top = S.base;
}
template <class QElemType>
Status stack<QElemType>::StackEmpty()
{
 if(S.top == S.base) return 1;
 else return 0;
}
template <class QElemType>
Status stack<QElemType>::StackLength()
{
 return (S.top - S.base);
}
template <class QElemType>
void stack<QElemType>::GetTop(QElemType & e)
{
 if(S.top != S.base)
  e = *(S.top - 1);
 else cout << "ERROR" << endl;
}
template <class QElemType>
void stack<QElemType>::Push(QElemType e)
{
 if(S.top - S.base >= S.stacksize)
 {
  S.base = (QElemType *)realloc(S.base,(S.stacksize + STACKINCREMENT) * sizeof(QElemType));
  if(!S.base) exit(0);
  S.top = S.base + S.stacksize;
  S.stacksize += STACKINCREMENT;
 }
 *S.top++ = e;
}
template <class QElemType>
void stack<QElemType>::Pop(QElemType & e)
{
 if(S.top == S.base) cout << "ERROR" << endl;
 else
  e = * --S.top;
}
//********* ****栈实现结束

 

 


//********图的实现
//*********Graph.h图的实现

template <class TElemType>
class Graph
{
 public:
  void CreateAlgraph();
  void DestroyAlgraph();
  void TopologicalSort();                              //有向图拓扑排序,检验环的存在与否
  float * TopologicalOrder(stack<int> &sre,int &e);
  void Criticalpath();            //求有向无环图关键路径
 private:
  int count;

  struct Arcnode       
  {
   int adjvex;
   Arcnode *nextarc;
   float weight;
  };
  template <class TElemType>
  struct Vexnode
  {
   TElemType data;
   Arcnode *firarc;
  };
  struct ALgraph
  {
   int vexnum;
   int arcnum;
   bool kind;
   Vexnode<TElemType> *vex;
  };
  ALgraph algraph;           //邻接表存储
};

template <class TElemType>
void Graph<TElemType>::CreateAlgraph()
{
 int i,j,m,n;
 float w;
 TElemType v1,v2;
 Arcnode *p;
 cout << "输入图类型(1是无向图,0是有向图):" << endl;
 cin >> algraph.kind;
 cout << "输入顶点数和边数:" << endl;
 cin >> algraph.vexnum >> algraph.arcnum;
 algraph.vex = (Vexnode<TElemType> *)malloc(algraph.vexnum * sizeof(Vexnode<TElemType>));
 cout << "输入顶点信息:" << endl;
 for(i = 0;i < algraph.vexnum;i++)
 {
  cin >> algraph.vex[i].data;
  algraph.vex[i].firarc = NULL;
 }

 if(algraph.kind)
 {
  cout << "输入各边依附的两点和权值:" << endl;
  for(i = 0;i < algraph.arcnum;i++)
  {
   cin >> v1 >> v2 >>w;
   for(j = 0;j < algraph.vexnum;j++)
   {
    if(v1 == algraph.vex[j].data) m = j;
    if(v2 == algraph.vex[j].data) n = j;
   }
   p = (Arcnode *)malloc(2*sizeof(Arcnode));
   p[0].adjvex = n;p[0].weight = w;
   p[1].adjvex = m;p[1].weight = w;
   p[0].nextarc = algraph.vex[m].firarc;algraph.vex[m].firarc = p;
   p[1].nextarc = algraph.vex[n].firarc;algraph.vex[n].firarc = ++p;
  }
 }

 else
 {
  cout << "输入各边的弧尾与弧头结点及有向边的权值:" << endl;
  for(i = 0;i < algraph.arcnum;i++)
  {
   cin >> v1 >> v2 >> w;
   for(j = 0;j < algraph.vexnum;j++)
   {
    if(v1 == algraph.vex[j].data) m = j;
    if(v2 == algraph.vex[j].data) n = j;
   }
   p = (Arcnode *)malloc(sizeof(Arcnode));
   p->adjvex = n;p->weight = w;
   p->nextarc = algraph.vex[m].firarc;algraph.vex[m].firarc = p;
  }
 }
}                 //构造完成


template <class TElemType>
void Graph<TElemType>::DestroyAlgraph()
{
 int i;
 Arcnode *p,*q;
 for(i = 0;i < algraph.vexnum;i++)
 {
  p = algraph.vex[i].firarc;
  if(p)
  {
   q = p->nextarc;
  while(q)
  {
   free(p);
   p = q;
   q = q->nextarc;
  }
  free(p);
  }
 }
 free(algraph.vex);
}

template <class TElemType>
float * Graph<TElemType>::TopologicalOrder(stack<int> &sre,int &e)
{
 stack<int> topo;
 topo.InitStack();
 sre.InitStack();
 float *re = (float *)malloc(algraph.vexnum * sizeof(float));
 int *indegree = (int *)malloc(algraph.vexnum * sizeof(int));
 int i,v,v1,count = 0;
 for(i = 0;i < algraph.vexnum;i++) re[i] = 0;

 Arcnode *p;
 for(i = 0;i < algraph.vexnum;i++) indegree[i] = 0;
 for(i = 0;i < algraph.vexnum;i++)
  for(p = algraph.vex[i].firarc;p;p = p->nextarc)
  {
   v = p->adjvex;
   indegree[v]++;
  }
  for(i = 0;i < algraph.vexnum;i++)
   if(indegree[i] == 0) topo.Push(i);
   while(!topo.StackEmpty())
   {
    topo.Pop(v);
    sre.Push(v);
    count++;
    for(p = algraph.vex[v].firarc;p;p = p->nextarc)
    {
     v1 = p->adjvex;
     if(0 == --indegree[v1]) topo.Push(v1);
     if(re[v] + p->weight > re[v1]) re[v1] = re[v] + p->weight;
    }
   }
   e = v;
   topo.DestroyStack();
   if(count < algraph.vexnum) return NULL;
   return re;
}


template <class TElemType>
void Graph<TElemType>::Criticalpath()
{
 float *rl = (float *)malloc(algraph.vexnum * sizeof(float));
 stack<int> sre;
 int e;
 float *re = TopologicalOrder(sre,e);
 if(re)
 {
 int i,v,v1;
 Arcnode *p;
 for(i = 0;i < algraph.vexnum;i++) rl[i] = re[e];
 while(!sre.StackEmpty())
 {
  sre.Pop(v);
  for(p = algraph.vex[v].firarc;p;p = p->nextarc)
  {
   v1 = p->adjvex;
   if(rl[v1] - p->weight < rl[v]) rl[v] = rl[v1] - p->weight;
  }
 }
    cout << "关键路径如下:" << endl;
 for(i = 0;i < algraph.vexnum;i++)
  for(p = algraph.vex[i].firarc;p;p = p->nextarc)
  {
   v1 = p->adjvex;
   if(rl[v1]-p->weight == re[i]) cout << "(" << algraph.vex[i].data << "," << algraph.vex[v1].data << ") ";
  }
  cout << endl;
  free(re);
 }
 else cout << "有向图中存在环,不合要求!" << endl;
  free(rl);
  sre.DestroyStack();
}


//小测试程序test.cpp


int main()
{
 Graph<int> gph;
 gph.CreateAlgraph();
 gph.Criticalpath();
 gph.DestroyAlgraph();
 return 0;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值