学习记录~~
#include<iostream>
using namespace std;
const int MaxSize = 100;
const int MaxInt = 32767;
typedef string DataType;
const int MaxEdge = 100;
struct EdgeNode
{
int adjvex;
int weight;
EdgeNode* next;
};
struct VertexNode
{
DataType vertex;//顶点信息
int in_Top_Num;//每个顶点入度(求拓扑序列时会递减)
int inNum;//每个顶点入度
int in[MaxSize];//狐尾顶点的下标
int outNum;//每个顶点出度
int out[MaxSize];//狐头顶点的下标
EdgeNode* firstEdge;
};
struct EdgeType
{
int from, to;
int weigth;
};
class ALGraph
{
private:
EdgeType edge[MaxEdge];//边集数组
VertexNode adjList[MaxSize];
int vertexNum, edgeNum;
int Max(int i);
int Min(int i);
public:
ALGraph(DataType a[], int n, int e);
~ALGraph();
int *TopSort();//返回拓扑序列下标
void CriticalPath(int *Top);
};
int vl[MaxSize], ve[MaxSize], ee[MaxSize], el[MaxSize],el_ee[MaxSize];
/*
0 1 4
0 2 3
1 2 2
2 3 4
1 3 6
*/
int main()
{
DataType s[] = { "v0","v1","v2","v3" };
ALGraph G(s, 4, 5);
G.CriticalPath(G.TopSort());
return 0;
}
ALGraph::ALGraph(DataType a[], int n, int e)
{
vertexNum = n;
edgeNum = e;
int i, j, k, w=0;
int* rd = new int[vertexNum];
int* cd = new int[vertexNum];
for (i = 0; i < vertexNum; i++)
cd[i] = rd[i] = 0;
for (i = 0; i < vertexNum; i++)
{
adjList[i].vertex = a[i];
adjList[i].firstEdge = NULL;
adjList[i].in_Top_Num = 0;
adjList[i].inNum = 0;
adjList[i].outNum = 0;
}
for (k = 0; k < edgeNum; k++)
{
cin >> i >> j >> w;
EdgeNode* s = new EdgeNode;
s->adjvex = j;
s->weight = w;
s->next = adjList[i].firstEdge;
adjList[i].firstEdge = s;
adjList[j].in_Top_Num++;
adjList[j].inNum++;
adjList[j].in[rd[j]++] = i;//j顶点的入度加一后这里把以j顶点做狐头的狐的狐尾顶点的下标存起来
adjList[i].outNum++;
adjList[i].out[cd[i]++] = j;//i顶点的出度加一后这里把以i顶点做为狐尾的狐的狐头的下标存起来
edge[k].from = i;
edge[k].to = j;
edge[k].weigth = w;
}
delete[]rd;
delete[]cd;
}
ALGraph::~ALGraph()
{
int i, j;
EdgeNode* p = NULL, * q = NULL;
for (i = 0; i < vertexNum; i++)
{
p = q = adjList[i].firstEdge;
while (p != NULL)
{
p = p->next;
delete q;
q = p;
}
}
}
int* ALGraph::TopSort()
{
int Start[MaxSize],top=-1;
int *topxl=new int[MaxSize];//保存拓扑序列下标
int i, j, k, count = 0;
EdgeNode* p = NULL;
for (i = 0; i < vertexNum; i++)
{
if (adjList[i].in_Top_Num==0)
Start[++top] = i;
}
while (top != -1)
{
j = Start[top--];
cout << adjList[j].vertex<<" ";
topxl[count++] = j;
p = adjList[j].firstEdge;
while (p != NULL)
{
k = p->adjvex;
adjList[k].in_Top_Num--;
if (adjList[k].in_Top_Num == 0)
Start[++top] = k;
p = p->next;
}
}
if (count == vertexNum)
return topxl;
if (count < vertexNum)
{
cout << "有回路\n";
return NULL;
}
delete[]topxl;
}
int ALGraph::Max(int i)
{
int max_ve =-1,w=0;
for (int j = 0; j < adjList[i].inNum; j++)
{
for (int k = 0; k < edgeNum; k++)
{
if (edge[k].to == i && edge[k].from == adjList[i].in[j])
{
w = edge[k].weigth;
break;
}
}
if (ve[adjList[i].in[j]] + w > max_ve)
max_ve = ve[adjList[i].in[j]] + w;
}
return max_ve;
}
int ALGraph::Min(int i)
{
int w, min_vl=MaxInt;
for (int j = 0; j < adjList[i].outNum; j++)
{
for (int k = 0; k < edgeNum; k++)
{
if (edge[k].from == i && edge[k].to == adjList[i].out[j])
{
w = edge[k].weigth;
break;
}
}
if (vl[adjList[i].out[j]] - w < min_vl)
min_vl = vl[adjList[i].out[j]] - w;
}
return min_vl;
}
void ALGraph::CriticalPath(int* Top)
{
int i, j = 0, w = 0;
cout << "\n拓扑序列为\n";
for (i = 0; i < vertexNum; i++)
cout << adjList[Top[i]].vertex << " ";
cout << endl;
for (i = 0; i < vertexNum; i++)
{
if (i == 0)
ve[Top[i]] = 0;
else
ve[Top[i]] = Max(Top[i]);
cout << "顶点" << adjList[Top[i]].vertex << "的最早发生时间ve=" << ve[Top[i]] << endl;
}
cout << endl;
for (i = vertexNum - 1; i >= 0; i--)
{
if (i == vertexNum - 1)
vl[Top[i]] = ve[Top[i]];
else
vl[Top[i]] = Min(Top[i]);
cout << "顶点" << adjList[Top[i]].vertex << "的最迟发生时间vl=" << vl[Top[i]] << endl;
}
cout << endl;
for (j = 0; j < edgeNum; j++)
{
ee[j] = ve[edge[j].from];
el[j] = vl[edge[j].to] - edge[j].weigth;
el_ee[j] = el[j] - ee[j];
}
for (j = 0; j < edgeNum; j++)
cout << "下标为" << j << "的边的最早发生时间ee=" << ee[j] << endl;
cout << endl;
for (j = 0; j < edgeNum; j++)
cout << "下标为" << j << "的边的最迟发生时间el=" << el[j] << endl;
cout << endl;
cout << "时间余量为0的边为关键活动\n";
for (j = 0; j < edgeNum; j++)
cout << "下标为" << j << "的边的时间余量el-ee=" << el_ee[j] << endl;
cout << endl;
int sum = vl[Top[vertexNum - 1]];
w = 0;
cout << "关键路径为为:\n";
for (i = 0; i < edgeNum; i++)
{
if (w == sum)
break;
if (el_ee[i] == 0)
{
cout << "("<<adjList[edge[i].from].vertex << " ";
cout << edge[i].weigth<<" ";
cout << adjList[edge[i].to].vertex << ")";
w+= edge[i].weigth;
}
}
}