关键路径

来源:互联网 发布:linux安装tar.gz文件 编辑:程序博客网 时间:2024/04/27 23:50

#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;
}

原创粉丝点击