Topological Sort + make + UVa10305 (Ordering Tasks)

  Topological sorting is widely used in practice. First look at an example, open source software, often built using GNU make tools to manage the project. Item here is constituted by a number of objects, the Makefile document describes the construction of the rule of these objects, specifically, these rules are dependencies among the list of objects: if the object A is dependent on object B, then object B must first be described A construction of the object, otherwise it will not be able to build. The task is to make reasonable arrangements for each sequence of objects built so that the process can be completed successfully.

  As an example, the contents of a Makefile as follows:

target: foo.o bar.o

foo.o: foo.c foo.h
bar.o: bar.c bar.h

  To solve this problem, we first mathematical transformation of the problem. DAG used to represent the dependencies between each object, each of vertices of the graph represents an object with the line segment starting at the end must be constructed, i.e., dependent on the starting point of the end.

  How rational distribution of each object build order, so that the construction process can proceed smoothly it? Intuitive idea is to choose not to be dependent on other objects as a first object; consider a second object, which in addition to the selected first object, should not be other objects dependent; Choice of n objects, in addition to its first 1 ~ n-1 previously selected objects, other objects can not be relied upon. According to this rule in order to select an object, you can ensure that the build process successfully concluded.

  In graph theory, such a similar strategy called topology sorting algorithm. Topological Sort Sort all the vertices are linear, not a topological sorting node pointing to its previous node, formally describe: the drawings, any two nodes u and v, if there is a directed edge pointing from u v, then the topological sort u must appear in front v.

  FIG topological sort to have necessary and sufficient condition is the presence of the DAG graph (directed acyclic graph), this conclusion for determining whether the problem has a solution, but also for determining whether there is a circumferential FIG.

 

  Solution process algorithm is as follows: First of all vertices statistics penetration . then:

a. Looking for all the degrees of vertex 0, sort results added and removed from the drawing, while all the vertices (adjacent vertices) which is directed into a reduced degree.
b. Repeating a, it is removed from the graph until all the vertices.


  With respect to the ring may be any of a directed graph, looking into the degree of vertex 0, and if not, FIG topological sort described is not present, i.e., the problem has no solution.

 

  Above "remove" is the concept of logical level, the specific implementation, we really do not need to be removed from the apex of the figure, because some times a. The degree found in the vertex 0 may only appear once on a . in the degree of the vertex is decremented. When a find-degree vertex 0, putting it into the degrees of adjacent vertices minus one, then the way will be reduced to statistics of the vertices 0, the next time a degree from these into direct vertex 0 starts, no longer looking into the entire figure of the vertex 0.

 

  Finally, the subject of a UVa to illustrate specific algorithm to achieve:

UVa10305(Ordering Tasks)

Subject to the effect

  Given a bunch of tasks, a task which can only be executed after all its dependent tasks are completed. Known relationship between tasks, seeking possible execution order.

analysis

  Examples of the same ideas and make. As used herein, vector store adjacency tables, arrays deg_in maintain the degree of each vertex queue que maintenance trip in each of the vertices is reduced to 0.

Reference Code

#include <iostream>
#include <queue>
#define N 100+2

using namespace std;

static vector<int> con[N];
static int deg_in[N];

int main(void) {
    ios::sync_with_stdio(false);
    
    int n,m;
    while((cin >> n >> m) && n) {
        for(int i=1;i<=n;++i) {
            con[i].clear();
            deg_in[i] = 0;
        }
        
        for( Int I = 0 ; I <m; ++ I) {
             int A, J; 
            CIN >> >> A J; 
            CON [A] .push_back (J);
             ++ deg_in [J]; 
        } 
        
        // 
        // find the first vertex is 0
         //
         Queue < int > que; 
        Vector < int > ANS;
         for ( int I = . 1 ; I <= n-; ++ I) {
             IF (! {deg_in [I]) 
                que.push (I); 
            } 
        }
        
        //
        // 求排序中其它n-1个顶点
        //
        while(!que.empty()) {
            int u = que.front();
            que.pop();
            
            ans.push_back(u);
            
            for(size_t i=0; i<con[u].size(); ++i) {
                int t = con[u][i];
                if (--deg_in[t] == 0) {
                    que.push(t);
                }
            }
        }
        
        for(size_t i=0; i<ans.size(); ++i) {
            cout << ans[i] << (i==ans.size()-1 ? "" : " ");
        }
        cout << endl;
    }
    
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/sci-dev/p/11800821.html