1 #include"iostream" 2 #include"string" 3 #include"stack" 4 using namespace std; 5 typedef string element; 6 struct ArcNode{ //边结点 7 int weight; 8 int adjuex; 9 ArcNode *nextarc; 10 }; 11 struct VNode{ //顶点结点 12 element data; 13 ArcNode *firstarc; 14 }; 15 16 class Graph{ 17 private: 18 VNode *vertex; 19 int vernum,arcnum; 20 public: 21 Graph(int vernum,int arcnum){ 22 this->vernum = vernum; 23 this->arcnum = arcnum; 24 vertex = new VNode[vernum]; 25 for(int i = 0;i < vernum;i++){ 26 vertex[i].firstarc = NULL; 27 } 28 } 29 int connected(element e){ 30 for(int i = 0;i < vernum;i++){ 31 if(e == vertex[i].data){ 32 return i; 33 } 34 } 35 cout<<"没有该顶点"<<endl; 36 return -1; 37 } 38 void cinCreate(){ 39 cout<<"输入"<<vernum<<"个顶点"<<endl; 40 for(int i = 0;i < vernum;i++){ 41 cin>>vertex[i].data; 42 } 43 cout<<"输入"<<arcnum<<"条边"<<endl; 44 element v1,v2; 45 int n1,n2; 46 for(i = 0;i < arcnum;i++){ 47 cin>>v1>>v2; 48 n1 = connected(v1); 49 n2 = connected(v2); 50 ArcNode *p = new ArcNode; 51 p->adjuex = n2; 52 cin>>p->weight; 53 p->nextarc = vertex[n1].firstarc; 54 vertex[n1].firstarc = p; 55 } 56 } 57 void show(){ 58 for(int i = 0;i < vernum;i++){ 59 ArcNode *p = vertex[i].firstarc; 60 while(p){ 61 cout<<"<"<<vertex[i].data<<", "<<vertex[p->adjuex].data<<">"<<" : "<<p->weight<<endl; 62 p = p->nextarc; 63 } 64 } 65 } 66 void topoSort(int *arr){ 67 stack<int> s; 68 //初始化indegree数组 69 int *indegree = new int[vernum]; 70 for(int i = 0;i < vernum;i++){ 71 indegree[i] = 0; 72 } 73 for(i = 0;i < vernum;i++){ 74 ArcNode *p = vertex[i].firstarc; 75 while(p){ 76 indegree[p->adjuex]++; 77 p = p->nextarc; 78 } 79 } 80 //入度为0的点入栈 81 for(i = 0;i < vernum;i++){ 82 if(!indegree[i]){ 83 s.push(i); 84 } 85 } 86 //其他为0点入栈 87 for(i = 0;i < vernum;i++){ 88 arr[i] = s.top(); 89 s.pop(); 90 ArcNode *p = vertex[arr[i]].firstarc; 91 while(p){ 92 if(!--indegree[p->adjuex]){ 93 s.push(p->adjuex); 94 } 95 p = p->nextarc; 96 } 97 } 98 } 99 void shortPath(){ 100 //调用拓扑排序 排列顺序 101 int *topolist = new int[vernum]; 102 topoSort(topolist); 103 104 //最早发生时间ve 105 int *ve = new int[vernum]; 106 memset(ve,0,vernum * sizeof(int)); //初始化,int型只能初始化为0或-1 107 for(int i = 0;i < vernum;i++){ //遍历所有结点 108 int k = topolist[i]; //依次取出拓扑序列 109 ArcNode *p = vertex[k].firstarc; //p指向k的邻接点 110 while(p){ //邻接点存在 111 int j = p->adjuex; //邻接点的位置(下标) 112 //在所有最早的时间中找到一个最迟的,(等待最迟的完成)代表该点的最早 113 if(ve[j] < ve[k] + p->weight){ //若k的最早时间 加 k到j 的时间 比j 的最早时间迟,存上最长时间(因为j点要等待它前面所有点完成,即时间最长的完成) 114 ve[j] = ve[k] + p->weight; //ve[j]存上最早时间 115 } 116 p = p->nextarc; 117 } 118 } 119 120 //最晚发生时间vl 121 int *vl = new int[vernum]; 122 for(i = 0;i < vernum;i++){ //初始化为汇点的最早时间 123 vl[i] = ve[vernum - 1]; 124 } 125 for(i = vernum - 1;i >= 0;i--){ 126 int k = topolist[i]; 127 ArcNode *p = vertex[k].firstarc; 128 while(p){ 129 int j = p->adjuex; //邻接点 130 if(vl[k] > vl[j] - p->weight){ //若j最迟时间 减 k到j的时间 比 k的最迟时间早,存最早(在所有最迟时间中找到一个最早的作为最迟时间,以保证所有的都不会迟到) 131 vl[k] = vl[j] - p->weight; 132 } 133 p = p->nextarc; 134 } 135 } 136 137 //判断某活动是否为关键活动 138 for(i = 0;i < vernum;i++){ 139 ArcNode *p = vertex[i].firstarc; 140 while(p){ 141 int j = p->adjuex; //邻接点 142 int e = ve[i]; //最早活动 143 int l = vl[j] - p->weight; //(最迟活动)邻接点最迟时间 减 i到j的时间 144 if(e == l){ //相等则为关键路径 145 cout<<"<"<<vertex[i].data<<", "<<vertex[j].data<<">"<<ends; 146 } 147 p = p->nextarc; 148 } 149 } 150 cout<<endl; 151 } 152 }; 153 /* 154 155 v1 v2 v3 v4 v5 v6 156 v1 v2 6 v3 v1 1 v1 v4 5 v2 v5 3 v6 v4 2 v3 v2 5 v3 v4 5 v6 v3 4 v3 v5 6 v5 v6 6 157 158 v0 v1 v2 v3 v4 v5 v6 v7 v8 159 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 160 */ 161 int main(){ 162 Graph g(9, 11); 163 g.cinCreate(); 164 // g.show(); 165 g.shortPath(); 166 167 return 0; 168 }