Before introducing the key paths, we will first introduce a topological sorting. In fact, I don't quite understand this concept. Generally speaking, it is a node that keeps going to the back node and does not return to the accessed node, determine whether a graph is in topological order. (1) Select a vertex output without a precursor in the directed graph, and (2) Delete the vertex and all the edges whose tails start with it. Until there is no node in the graph or there is no point with the inbound degree of 0.
On this basis, key paths are introduced, and edge weights are added based on topological sorting to complete the maximum path length from the start point to the completion point of a project. The longest path is the Key Path. All activities on the Key Path are key activities. The key activity is to find E (I) = L (I), the earliest time of occurrence is ve, and the latest time of occurrence is Vl. It is difficult for me to explain this concept. It is difficult to explain it clearly. Let's take a look at the examples. How to solve VE and Vl. Ve (0) = 0 start forward recurrence ve (j) = max {ve (I) + Dut (I, j)}; after finding ve, VL (n-1) =
Ve (n-1); backward recursion, VL (I) = min {VL (j)-Dut (I, j )};
# Include "graph. H"
# Include <stdio. h>
# Include <queue>
# Include <stack>
Using namespace STD;
// # Define debug
Stack <int> S; // Save the reverse topology order.
Int ve [max_vertex_num]; // record the earliest time
Int VL [max_vertex_num]; // record the latest time
/*************************************** ******/
/* Topological sorting */
/* Parameter: G */
/* Check whether the graph has a ring */
/*************************************** ******/
Void topologicalsort (const mgraph * g)
{
Int indegree [max_vertex_num]; // inbound
Int I, J;
For (I = 0; I <G-> vexnum; I ++)
{
Indegree [I] = 0;
Ve [I] = 0;
}
// Initialize the inbound Node
For (I = 0; I <G-> vexnum; I ++)
For (j = 0; j <G-> vexnum; j ++)
{
If (G-> arcs [I] [J]! = Int_max)
{
Indegree [J] ++;
}
}
Int COUNT = 0; // number of output nodes
Queue <int> q; // point where the storage degree is 0
For (I = 0; I <G-> vexnum; I ++)
{
If (! Indegree [I])
{
Q. Push (I );
Indegree [I] --; // indicates that the queue has been entered.
}
}
// Output the point with an inbound degree of 0 in sequence
// If no vertex is output, the inbound value of the connected vertex is reduced by 1.
// Add the vertex with the input degree 0 to the queue.
While (! Q. Empty ())
{
Int temp;
Temp = Q. Front ();
S. Push (temp); // stack in reverse order
// Printf ("% d", G-> vexs [I]);
Count ++;
For (I = 0; I <G-> vexnum; I ++)
{
If (G-> arcs [temp] [I]! = Int_max)
{
Indegree [I] --; // delete a node. The inbound degree of the adjacent node is reduced by 1.
If (VE [temp] + G-> arcs [temp] [I])> ve [I])
{
Ve [I] = ve [temp] + G-> arcs [temp] [I]; // modify the earliest time
}
}
}
Q. Pop ();
For (I = 0; I <G-> vexnum; I ++)
{
If (! Indegree [I])
{
Q. Push (I );
Indegree [I] --;
}
}
}
If (count! = G-> vexnum)
Printf ("there is a ring! \ N ");
Else
{
// Printf ("Topology Sorting is complete! \ N ");
# Ifdef debug
For (I = 0; I <G-> vexnum; I ++)
Printf ("% d", ve [I]);
Printf ("\ n ");
# Endif
}
}
// When finding the latest occurrence time, I directly copy the method to find the earliest occurrence time
// Starts from outbound to inbound.
Void criticalpath (const mgraph * g)
{
// Int outdegree [max_vertex_num]; // outbound
Int I, J;
For (I = 0; I <G-> vexnum; I ++)
{
// Outdegree [I] = 0;
Vl [I] = int_max; // assign the maximum value here, and the minimum value is obtained.
}
/* For (I = 0; I <G-> vexnum; I ++)
For (j = 0; j <G-> vexnum; j ++)
{
If (G-> arcs [I] [J]. adj! = Int_max)
{
Outdegree [I] ++;
}
}
*/
Int count; // number of output nodes
Count = S. Top ();
Vl [count] = ve [count];
Count = 0;
// Queue <int> q; // point where the storage degree is 0
/* For (I = 0; I <G-> vexnum; I ++)
{
If (! Outdegree [I])
{
Q. Push (I );
Vl [I] = ve [I]; // value assignment
}
}
* /// Output the point with an inbound degree of 0 in sequence
// If no vertex is output, the inbound value of the connected vertex is reduced by 1.
// Add the vertex with the input degree 0 to the queue.
While (! S. Empty ())
{
Int temp;
Temp = S. Top ();
// Printf ("% d", G-> vexs [I]);
Count ++;
For (I = 0; I <G-> vexnum; I ++)
{
If (G-> arcs [I] [temp]! = Int_max) // The Arc ending with the delete knots
If (VL [temp]-g-> arcs [I] [temp]) <VL [I])
{
Vl [I] = VL [temp]-g-> arcs [I] [temp];
}
}
S. Pop ();
/* For (I = 0; I <G-> vexnum; I ++)
{
If (! Indegree [I])
Q. Push (I );
}
*/}
// Obtain the latest time and compare it with the earliest time. ..
If (count! = G-> vexnum)
Printf ("there is a ring! \ N ");
Else
{
Printf ("Key Path :");
# Ifdef debug
For (I = 0; I <G-> vexnum; I ++)
Printf ("% d", VL [I]);
# Endif
}
For (I = 0; I <G-> vexnum; I ++)
If (VL [I] = ve [I])
Printf ("% d", G-> vexs [I]);
}
/* Test
9 11
1 2 3 4 5 6 7 8 9end
1 2 6
1 3 4
1 4 5
2 5 1
3 5 1
4 6 2
5 7 9
5 8 7
6 8 4
7 9 2
8 9 4
End */