/*
Name: The critical path for topological sequencing (depth-first search)
Copyright:
Author: A clever clumsy
Date:17-11-14 21:02
Description: The key path of topological sequencing
In a weighted graph, the event is represented by a vertex, an activity is represented by a forward edge, and the weight on the edge represents the cost of the activity, such as the duration of the activity.
Then this weighted graph is called the network of activity on edge network, referred to as AOE net.
(1) The properties of AOV net
⒈ only when the event represented by a vertex has occurred, the activities represented by each of the forward edges from that vertex can begin.
⒉ only the events represented by each of the forward edges entering a vertex have ended and the event represented by that vertex can occur.
The ⒊ indicates that the AOE network of the actual engineering plan should be non-circular and there is a unique completion vertex for the start vertex and the unique out-of-0 for the 0.
(2) by the definition of the earliest occurrence time and the latest occurrence time of event V J, the following steps can be taken to obtain the key activities:
1. Starting from vertex v 1, make ve (1) = 0, according to the sequence of the topological order to find the possible earliest time of the remaining vertices.
Ve (k) =max{ve (j) +dut (<j,k>)} (7.1)
J∈t
Where T is the set of overhead points (2≤k≤n) of all arcs with Vertex v K as the tail.
If the number of vertices in an ordered sequence is smaller than the number of vertices in the net, then there is a ring in the net, the key path cannot be obtained, and the algorithm ends.
2. Starting from the completion vertex v N, make VL (n) =ve (n), according to the inverse topological sequence, the last time allowed for the remaining vertices:
VL (j) =min{vl (k)-dut (<j,k>)}
K∈s
Where S is the end vertex set (1≤j≤n-1) of all arcs with Vertex v J being the head.
3. Find the earliest start time for each activity a I (1≤I≤M) e (i) =ve (j); Latest Start time
L (i) =VL (k)-dut (<j,k>)
。 If an arc satisfies e (i) =l (i), it is a key activity.
Input:
The first line, two integers, n,m the number of vertices and edges, respectively, where the vertex number is 0~n-1.
The next M-line, each line has three number u,v,w, representing the weight of the edge from the arc tail u to the Arc Head v W.
8 10
0 1 5
0 2 4
1 4 3
2 3 2
3 4 1
4 5 6
4 6 6
5 7 2
6 7 2
4 7 8
Output:
Outputs all critical paths and outputs one critical path per line. The format is as follows:
0->1->4->7
0->1->4->5->7
0->1->4->6->7
Algorithm Analysis:
The first occurrence time of each vertex event is computed by using depth-first search for topological ordering, and then calculating the earliest occurrences of the vertices events at the same time.
This paper is the "Big talk data Structure" reading notes, in the output of critical path using depth-first search output critical path, can output a number of key paths.
*/
#include <stdio.h>
#include <stdlib.h>
#define MAXN 26//maximum number of vertices
#define MAXM 100000//MAX side number
typedef int VERTEXTYPE; Vertex types are custom-defined by the user
typedef int EDGETYPE; The weight type on the edge is custom-defined by the user
typedef struct edgenode{//Benzi node
int Adjvex; adjacency point field, which stores the subscript corresponding to the vertex
Edgetype weight; For a non-grid diagram, it is not necessary to
struct Edgenode *next; Chain field, pointing to the next adjacency point
} Edgenode;
typedef struct vertexnode{//Vertex table node
Vertextype data; Vertex fields, storing vertex information
int in; Number of storage vertex-in degrees
Edgenode *firstedge; Edge table Header pointer
} Vertexnode;
void Creategraph (Vertexnode *gl, int n, int m);//The Vertex and edge information is read into the adjacency table of the representation graph
int Topologicalsort_dfs (int topo[], int etv[], vertexnode *gl, int n);//Depth First search gets topological sequence
void Criticalpath (Vertexnode *gl, int n);//Seeking critical path
void Printpath (Vertexnode *gl, int etv[], int ltv[], int path[], int top, int end);//Depth First search output critical path
int main ()
{
int I, M, N;
Vertexnode GL[MAXN];
printf ("Please enter the number of vertices and the number of sides:");
scanf ("%d%d", &n, &m);
Creategraph (GL, N, m);//The Vertex and edge information is read into the adjacency table of the representation graph
Criticalpath (GL, n);//Find critical path
return 0;
}
void Creategraph (Vertexnode *gl, int n, int m)//The vertex and edge information is read into the adjacency table of the representation graph
{
int i, u, v;
Edgenode *e;
for (i=0; i<n; i++)//initialization diagram
{
Gl[i].data = i;
gl[i].in = 0;
Gl[i].firstedge = NULL;
}
for (i=0; i<m; i++)
{
E = (edgenode*) malloc (sizeof (Edgenode)); Inserting edge table nodes with head interpolation method
if (!e)
{
Puts ("Error");
Exit (1);
}
scanf ("%d%d%d", &u, &v, &e->weight);
E->next = Gl[u].firstedge;
Gl[u].firstedge = e;
E->adjvex = v;
gl[v].in++;
}
}
int Topologicalsort_dfs (int topo[], int etv[], vertexnode *gl, int n)//depth First search get topological sequence
{
int i, u, V, top, count = 0;
Edgenode *e;
int *stack;
Stack = (int*) malloc (sizeof (int) * n); Allocating stack space
if (! Stack)
{
Puts ("Error");
Exit (1);
}
for (top=i=0; i<n; i++)//Enter the vertex of the 0 into the stack
{
Etv[i] = 0; Initialize each event with the earliest event 0
if (gl[i].in = = 0)
{
stack[top++] = i;
}
}
while (Top > 0)//Use depth first search to get topological sequence
{
U = stack[--top];
topo[count++] = u;
for (E=gl[u].firstedge; e!=null; e=e->next)//Reduce the adjacency point of U by 1 and put the vertex of the 0 into the stack
{
v = e->adjvex;
if (--gl[v].in = = 0)
stack[top++] = v;
if (Etv[v] < Etv[u] + e->weight)//Update the earliest occurrence time of each vertex event
ETV[V] = Etv[u] + e->weight;
}
}
Free (Stack);
return (count = = N), or//if count is less than the number of vertices, indicates that there is a ring
}
void Criticalpath (Vertexnode *gl, int n)//seeking critical path
{
int i, u, v;
Edgenode *e;
int TOPO[MAXN], PATH[MAXN];
int ETV[MAXN], ltv[maxn];//stores the earliest and latest occurrences of events
if (! Topologicalsort_dfs (topo, ETV, GL, N))
{
Puts ("No critical path exists");
Return
}
for (i=0; i<n; i++)
{
Ltv[i] = etv[n-1]; Initializes the last occurrence of events at the latest event
}
for (i=n-2; i>=0; i--)
{
U = topo[i];
for (E=gl[u].firstedge; e!=null; e=e->next)
{
v = e->adjvex;
if (Ltv[u] > Ltv[v]-e->weight)//Update the latest occurrence of each vertex event
Ltv[u] = ltv[v]-e->weight;
}
}
Path[0] = topo[0];
Printpath (GL, ETV, LTV, Path, 1, topo[n-1]);
}
void Printpath (Vertexnode *gl, int etv[], int ltv[], int path[], int top, int end)//depth First search output critical path
{
int i, u = path[top-1];
Edgenode *e;
if (U = = end)
{
printf ("%d", path[0]); Output critical path
for (I=1; i<top; i++)
{
printf ("->%d", Path[i]);
}
printf ("\ n");
Return
}
for (E=gl[u].firstedge; e!=null; e=e->next)
{
if (Etv[e->adjvex] = = Ltv[e->adjvex])//Key Event
{
path[top++] = e->adjvex; Into the stack
Printpath (GL, ETV, LTV, Path, top, end);
top--; Back stack
}
}
}
Topology sequencing critical path (depth first search)