程序小白,希望和大家多交流,共同学习
//TopSort拓扑排序
#include<iostream>
#include<string>
#include<queue>
#define MAX_VN 50
#define INF 32767
using namespace std;
typedef string VertexData;
struct ArcNode{
int adjvex;
int weight;
ArcNode *nextArc;
};
struct Vertex{
VertexData data;
ArcNode *firstArc;
};
struct AdjList{
Vertex vertex[MAX_VN];
int verNum, arcNum;
};
void createAdjList(AdjList &G);
int locateVertex(AdjList &G, VertexData data);
void outputAdjList(AdjList &G);
void topOrder(const AdjList &G,int *order);
void printTopOder(const AdjList &G,int *order);
//关键路径
void criticalPath(const AdjList &G);
int main(){
/* 9 11 V0 V1 V2 V3 V4 V5 V6 V7 V8 V0 V1 6 V0 V2 4 V0 V3 5 V1 V4 1 V2 V4 1 V3 V5 2 V4 V6 9 V4 V7 7 V5 V7 4 V6 V8 2 V7 V8 4 */
AdjList G;
createAdjList(G);
outputAdjList(G);
cout << "TopOrder:" << endl;
int *order = new int[G.verNum + 1];
topOrder(G, order);
printTopOder(G, order);
criticalPath(G);
return 0;
}
void createAdjList(AdjList &G){
cout << "输入顶点个数和弧的条数:";
cin >> G.verNum >> G.arcNum;
cout << "输入顶点信息:";
for (int i =1; i <= G.verNum; i++){
cin >> G.vertex[i].data;
G.vertex[i].firstArc = NULL;//初始化
}
cout << "输入各条弧的信息:";
VertexData u, v;
int w;
int i, j;
for (int k = 1; k <= G.arcNum; k++){
cin >> u >> v >> w;
i = locateVertex(G, u);
j = locateVertex(G, v);
ArcNode *p = new ArcNode;
p -> weight = w;
p -> adjvex = j;
p -> nextArc = G.vertex[i].firstArc;
G.vertex[i].firstArc = p;
}
}
int locateVertex(AdjList &G, VertexData data){
for (int i = 1; i <= G.verNum; i++){
if (G.vertex[i].data == data){
return i;
}
}
return -1;
}
void outputAdjList(AdjList &G){
for (int i = 1; i <= G.verNum; i++){
cout << i << " ";
cout << G.vertex[i].data << " -> ";
ArcNode *p = G.vertex[i].firstArc;
while (p){
cout << p -> adjvex << " " << p -> weight << " -> ";
p = p -> nextArc;
}
cout << " ^" << endl;
}
}
void topOrder(const AdjList &G, int *order){
//初始化入度为零
int *inDegrees = new int[G.verNum + 1];
for (int i = 1; i <= G.verNum; i++){
inDegrees[i] = 0;
}
//按照G的结构更新度
ArcNode *p;
for (int i = 1; i <= G.verNum; i++){
p = G.vertex[i].firstArc;
while (p){
int j = p -> adjvex;
inDegrees[j]++;
p = p -> nextArc;
}
}
//将度为0的加入队列
queue<int> q;
for (int i = 1; i <= G.verNum; i++){
if (inDegrees[i] == 0){
q.push(i);
}
}
//按照出队列的方式,将度为0的入栈,并将此顶点的邻接点的度减一
//根据出栈顺序,将每次出栈的顶点记录在order中
int k = 0;
while (k < G.verNum){
int z = q.front();
q.pop();//返回栈顶元素之后要出栈
order[++k] = z;
p = G.vertex[z].firstArc;
while (p){
int j = p -> adjvex;
inDegrees[j]--;
if (inDegrees[j] == 0){
q.push(j);
}
p = p -> nextArc;
}
}
delete []inDegrees;
}
void printTopOder(const AdjList &G, int *order){
for (int i = 1; i <= G.verNum; i++){
cout << G.vertex[order[i]].data << " ";
}
cout << endl;
}
void criticalPath(const AdjList &G){
int n = G.verNum;
int *ve = new int[n + 1];
int *vl = new int[n + 1];
int *order = new int[n + 1];
topOrder(G, order);
for (int i = 1; i <= n; i++){
cout << G.vertex[order[i]].data << " ";
}
cout << endl;
//ve
for (int i = 1; i <= n; i++){
ve[i] = 0;
}
for (int i = 1; i <= n; i++){
int u = order[i];
ArcNode *p = G.vertex[u].firstArc;
while (p){
int j = p -> adjvex;
if (ve[j] < ve[u] + p -> weight){
ve[j] = ve[u] + p -> weight;
}
p = p -> nextArc;
}
}
for (int i = 1; i <= n; i++){
printf("%-3d", ve[i]);
}
cout << endl;
//vl
for (int i = 1; i <= n; i++){
vl[i] = ve[n];
}
for (int i = n - 1; i >= 1; i--){
int u = order[i];
ArcNode *p = G.vertex[u].firstArc;
while (p){
int j = p -> adjvex;
if (vl[u] > vl[j] - p -> weight){
vl[u] = vl[j] - p -> weight;
}
p = p -> nextArc;
}
}
for (int i = 1; i <= n; i++){
printf("%-3d", vl[i]);
}
cout << endl;
//关键路径
//其实ve和vl都是在存储关键路径,最大ve是加法,加的最多所以最大,那么加的最多的是关键路径
//最小vl是减法,减的最多所以最小,那么减的最多的是关键路径
cout << "关键路径是:";
int ee, el;
for (int i = 1; i < n; i++){
int u = order[i];
ee = ve[u];
ArcNode *p = G.vertex[u].firstArc;
while (p){
int j = p -> adjvex;
el = vl[j] - p -> weight;
if (ee == el){
cout << G.vertex[u].data << " -> " << G.vertex[j].data << endl;
}
p = p -> nextArc;
}
}
delete []ve;
delete []vl;
delete []order;
}