6 获取AOE网的关键路径
作者: 冯向阳时间限制: 1S章节: 课程设计
问题描述 :
建立一个有向网AOE网,设计并完成一算法Get_CriticalPath(),获取关键路径。该路径仅输出,不须保存。
提示:在AOE网中,
(1)关键活动:开始时间余量为0的活动。即活动的最早开始时间等于它的最迟开始时间。
(2)根据各个顶点的Ve和Vl值,在求得每条弧s的最早开始时间e[s]和最迟开始时间l[s]后,若某条弧满足条件e[s]=l[s],该弧所对应的活动即为关键活动。
(3)关键路径:由关键活动所形成的从源点到汇点的每一条路径(注意:关键路径可能有多条)。
参考函数原型:
//获取AOE网各顶点事件的最早发生时间ve和最迟发生时间vl、活动ak的最早开始时间e和最迟开始时间l、一条关键路径
template<class TypeOfVer, class TypeOfEdge>
bool adjlist_graph<TypeOfVer, TypeOfEdge>::Get_CriticalPath(int ve[], int vl[]);
输入说明 :
第一行:图的类型
第二行:结点数
第三行:结点集
第四行:边数
第五行:边集
第六行:权集
输出说明 :
第一行:顶点集
第二行:邻接表
空行
顶点i Ve[i] Vl[i](列与列之间用格式控制符’\t’分隔)
…
空行
<弧尾,弧头> e[k] l[k](列与列之间用格式控制符’\t’分隔)
…
空行
<弧尾,弧头>-><弧尾,弧头>…
typedef char VerTexType;
typedef int ArcType;
struct line
{
int v1, v2;
int info;
};
typedef struct ArcNode
{
int adjvex; //该边所指向的顶点的位置
struct ArcNode* nexarc; //指向下一条边的指针
int info; //和边相关的信息
}ArcNode;
typedef struct VNode
{
char data;
ArcNode* firstarc; //指向第一条依附该顶点的边的指针
friend istream& operator >> (istream& istr, VNode& t) {
cin >> t.data;
return cin;
}
}VNode,AdjList[1000]; //AdjList表示邻接表类型
typedef struct //邻接表
{
AdjList vertices;
int vexnum, arcnum; //图的当前顶点数和边数
}ALGraph;
int LocateVex(ALGraph& G, int u)
{
for (int i = 0; i < 100; i++)
{
if (i == u)
return i;
}
return -1;
}
Status CreateUDG(ALGraph& G)
{
cin >> G.vexnum;
for (int i = 0; i < G.vexnum; ++i)
{
cin >> G.vertices[i].data;
G.vertices[i].firstarc = NULL;
}
cin >> G.arcnum;
int v1, v2;
int i, j;
line s[10000] = { 0 };
for (int k = 0; k < G.arcnum; ++k)
{
cin >> v1 >> v2;
s[k].v1 = v1;
s[k].v2 = v2;
}
for (int k = 0; k < G.arcnum; ++k)
{
cin >> v1 ;
s[k].info = v1;
}
for (int k = 0; k < G.arcnum; ++k)
{
v1 = s[k].v1 ;
v2 = s[k].v2;
i = LocateVex(G, v1); j = LocateVex(G, v2);
ArcNode *p1 = new ArcNode;
p1->adjvex = j;
p1->nexarc = G.vertices[i].firstarc;
p1->info = s[k].info;
G.vertices[i].firstarc = p1;
ArcNode* p2 = new ArcNode;
p2->adjvex = i;
p2->nexarc = G.vertices[j].firstarc;
p2->info = s[k].info;
G.vertices[j].firstarc = p2;
}
return 1;
}
Status CreateUDN(ALGraph& G)
{
cin >> G.vexnum;
for (int i = 0; i < G.vexnum; ++i)
{
cin >> G.vertices[i].data;
G.vertices[i].firstarc = NULL;
}
cin >> G.arcnum;
int v1, v2;
int i, j;
line s[10000] = { 0 };
for (int k = 0; k < G.arcnum; ++k)
{
cin >> v1 >> v2;
s[k].v1 = v1;
s[k].v2 = v2;
}
for (int k = 0; k < G.arcnum; ++k)
{
cin >> v1;
s[k].info = v1;
}
for (int k = 0; k < G.arcnum; ++k)
{
v1 = s[k].v1;
v2 = s[k].v2;
i = LocateVex(G, v1); j = LocateVex(G, v2);
ArcNode* p1 = new ArcNode;
p1->adjvex = j;
p1->nexarc = G.vertices[i].firstarc;
p1->info = s[k].info;
G.vertices[i].firstarc = p1;
}
return 1;
}
void displaycode(ALGraph& G)
{
for (int i = 0; i < G.vexnum; ++i) {
cout << G.vertices[i].data;
if (i != G.vexnum - 1)
cout << " ";
}
return;
}
void displaycodegraph(ALGraph& G)
{
for (int i = 0; i < G.vexnum; ++i) {
cout << G.vertices[i].data;
if (G.vertices[i].firstarc != NULL) {
cout << "->" << G.vertices[i].firstarc->adjvex << "(" << G.vertices[i].firstarc->info << ")";
ArcNode* p = G.vertices[i].firstarc->nexarc;
while (p != NULL ) {
cout << "->" << p->adjvex << "(" << p->info << ")";
p = p->nexarc;
}
}
cout << endl;
}
return;
}
int* findve(ALGraph& G)
{
int s[100] = { 0 };
int *ve = new int [100];
int i = 0,k=0;
for (i = 0; i < G.vexnum; i++){
int num = 0;
for (k = 0; k < G.vexnum; k++){
ArcNode* p = G.vertices[k].firstarc;
while (p != NULL){
if (p->adjvex == i) {
s[num] = p->info+ve[k];
num++;
break;
}
p = p->nexarc;
}
}
ve[i]= * max_element(s, s + num);
}
return ve;
}
int* findvl(ALGraph& G,int longest)
{
int s[100][100] = { 0 };
int *vl = new int [100] ;
int i = 0, k = 0;
int num[100] = { 0 };
for (i = 0; i < 100; i++)
vl[i] = 0;
vl[G.vexnum-1] = longest;
for (i = G.vexnum-1; i >= 0 ; i--) {
if (i!=G.vexnum-1)
vl[i] = *min_element(s[i], s[i] + num[i]);
for (k = 0; k < G.vexnum; k++) {
ArcNode* p = G.vertices[k].firstarc;
while (p != NULL) {
if (p->adjvex == i) {
s[k][num[k]] = - p->info + vl [i] ;
num[k] ++;
}
p = p->nexarc;
}
}
}
return vl;
}
int* finde(ALGraph& G, int* ve, int* vl)
{
int* e = new int[100];
int num = 0;
int i = 0 , k = 0;
for (i = 0; i < G.vexnum; i++) {
ArcNode* p = G.vertices[i].firstarc;
while (p != NULL) {
e[num] = ve[i] ;
num++;
p = p->nexarc;
}
}
return e;
}
int* findl(ALGraph& G, int* ve, int* vl)
{
int* l = new int[100];
int num = 0;
int i = 0, k = 0;
for (i = 0; i < G.vexnum; i++) {
ArcNode* p = G.vertices[i].firstarc;
while (p != NULL) {
l[num] = vl [p->adjvex] - p->info;
num++;
p = p->nexarc;
}
}
return l;
}
void dispalayall(ALGraph& G, int ve[], int vl[], int e[], int l[])
{
int num = 0;
for (int i = 0; i < G.vexnum; i++) {
cout << G.vertices[i].data << "\t" << ve[num] << "\t" << vl[num] << endl;
num++;
}
cout << endl;
num = 0;
for (int i = 0; i < G.vexnum; i++) {
ArcNode* p = G.vertices[i].firstarc;
while (p != NULL) {
cout << "<" << G.vertices[i].data << "," << G.vertices[p->adjvex].data << ">\t" << e[num] << "\t" << l[num] << endl;
num++;
p = p->nexarc;
}
}
cout << endl;
int ok = 1; num = 0;
for (int i = 0; i < G.vexnum; i++) {
ArcNode* p = G.vertices[i].firstarc;
while (p != NULL) {
if (e[num]==l[num]) {
if (ok != 1)
cout << "->";
cout << "(" << G.vertices[i].data << "," << G.vertices[p->adjvex].data << ")";
ok = 0;
}
p = p->nexarc;
num++;
}
}
}
bool Get_CriticalPath(ALGraph &S,int ve[], int vl[])
{
int* e = finde(S, ve, vl);
int* l = findl(S, ve, vl);
dispalayall(S, ve, vl , e, l);
return 1;
}