Quasi-linear algorithm for the component tree

L. Najman and M. Couprie Laboratoire A2SI, Groupe ESIEE Cit? Descartes, BP99 e 93162 Noisy-le-Grand Cedex France {l.najman,m.couprie}@esiee.fr September, 4, 2003

ABSTRACT

The level sets of an image are the sets of pixels with grey level above a given threshold. The connected components of the level sets, thanks to the inclusion relation, can be organized in a tree structure, that is called the component tree. Various algorithms have been proposed in the literature for computing the component tree. The fastest ones have been proved to run in 0(n ln(n)) complexity. In this paper, we propose a simple to implement quasi-linear algorithm for computing the component tree on symmetric graphes, based on Tarjan’s Union-Find principle. Keywords: Component tree, mathematical morphology

1. INTRODUCTION

The level sets of an image are the sets of pixels with grey level above a given threshold. The representation of an image by its level sets has been proposed by the Mathematical Morphology school as a decomposition that preserves the contrast under change of scale. The connected components of the level sets, thanks to the inclusion relation, can be organized in a tree structure, that is called the component tree. The component tree captures some essential features of the image, and allows to characterize some topological features of the image. Thus, it (or variation of it) has been used in numerous applications among which we can cite: image ?ltering and segmentation,1–4 matching,5 video segmentation, image registration6 and image compression. We also note that this tree is fundamental for the e?cient computation of the topological watershed introduced by M. Couprie and G. Bertrand.3 While having been (re)discovered by several authors for image processing applications, its the component tree concept takes root in statistics.7, 8 Various algorithms have been proposed in the literature for computing the component tree. The fastest ones have been proved to run in 0(n ln(n)) complexity. In this paper, we propose a quasi-linear algorithm for computing the component tree on general symmetric graphes, based on Tarjan’s Union-Find9 principle. We would like to emphasize that this algorithm is simple to implement. A proof of the complexity of this algorithm is given.

2. GRAPH STRUCTURE AND THE COMPONENT TREE 2.1. Basic notions for graphs

Let E be a ?nite set (set of vertices, or points). A graph G = (E, Γ) on E is de?ned through a mapping Γ from E to P(S), where P(E) denotes the set of all subsets of E. The mapping Γ associates to each point x of E, the set Γ(x) of points adjacent to x. A graph (E, Γ) is symmetric if for all x, y of S, y ∈ Γ(x) implies x ∈ Γ(y). Let X ? E. We denote by X the complementary set of X in E. The points of X are called the object points, the points of X are called the background points. Let X ? E, and let x0 , xn ∈ X. A path from x0 to xn in X is an ordered family (x0 , x1 , . . . , xn ) of points of X such that xi+1 ∈ Γ(xi ), with i = 0 . . . n ? 1. Let x, y ∈ X, we say that x is connected to y if there exists a

Corresponding author: L. Najman

path from x to y in X. The relation “is connected to” is an equivalence relation. A connected component of X is an equivalence class for the relation “is connected to”. Let Z denote the set of integers. Let w and h be two strictly positive integers, we denote by Z2 the cartesian product of the two subsets of Z: {0, . . . , w ? 1} and {0, . . . , h ? 1}. A point x ∈ Z2 is de?ned by its two coordinates (x1 , x2 ). We are going to illustrate this paper through binary images X ? Z2 , but the notions developed here are obviouly not limited to Z2 . Two adjacency relations can be considered on Z2 : Γ4 and Γ8 , de?ned by, for all x in Z2 : Γ4 (x) = {y ∈ Z2 ; |x1 ? y1 | + |x2 ? y2 | ≤ 1}, Γ8 (x) = {y ∈ Z2 ; max{|x1 ? y1 |, |x2 ? y2 |} ≤ 1}. The set Γn (x) is called the n-neighborhood of x (n = 4, 8). Two points x and y, x = y, are said to be n-adjacent if y ∈ Γn (x) ; we also say that y is an n-neighbor of x.

0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 1 0 1 1 1 0 0 1 0 1 0 0 0 0 0 0 0 1 1 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0

Figure 1. A binary image that has three 4-connected components, or two 8-connected components

In Fig. 1, a binary image is represented. The points marked “1” are object points and the points marked “0” are background points. We see that the set X of object points has two 8-connected components, and it has three 4-connected components (depending on which graph is used to de?ne the connectedness). In the following, we will assume that a graph Γn has been chosen to de?ne the connectivity, with n = 4 or n = 8, and the number n will not be written unless necessary.

2.2. Basic notions for weighted graphs

We denote by F(E) the set composed of all functions from E to Z. A function F ∈ F(E) represents a weighted graph. If E = Z2 , F is called a grayscale image (see Fig. 2(a)). Let F ∈ F(E), we de?ne Fk = {x ∈ E; F (x) ≥ k} with k ∈ Z; Fk is called a cross-section of F . A connected component of a section Fk is called a (level k) component of F . A level k component of F that does not contain a level (k + 1) component of F is called a (regional) maximum of F . We de?ne kmin = min {F (x), x ∈ E} and kmax = max {F (x), x ∈ E}, which represent respectively, the minimum and the maximum graylevel in the function F . Fig. 2 shows a grayscale image F and four cross-sections of F , between the level kmin = 1 and the level kmax = 4. The set F4 is made of two connected components which are regional maxima of F .

2.3. Component Tree

From the example of Fig. 2, we can see that the connected components of the di?erent cross-sections may be organized, thanks to the inclusion relation, to form a tree structure. The use of this tree in order to represent the “meaningful” information contained in a numerical function is not new. In particular, Hanusse and Guillataud1, 2 claim that this tree can play a central role in image segmentation, and suggest a way to compute it, based on an immersion simulation. Several authors, such as Vachier,10 Breen and Jones,11 Salembier et al.12 have used this structure in order to implement e?ciently some morphological operators (e.g. attribute openings, granulometries, extinction functions). Algorithms to compute

1 1 1 1 1 1 1

1 3 3 1 3 4 1

1 3 3 1 3 3 1

1 2 2 1 2 2 1

1 3 3 1 1 2 1

1 4 4 3 1 2 1

1 1 1 1 1 1 1

1 1 1 1 1 1 1

1 1 1 1 1 1 1

1 1 1 1 1 1 1

1 1 1 1 1 1 1

1 1 1 1 1 1 1

1 1 1 1 1 1 1

1 1 1 1 1 1 1

0 0 0 0 0 0 0

0 1 1 0 1 1 0

0 1 1 0 1 1 0

0 1 1 0 1 1 0

0 1 1 0 0 1 0

0 1 1 1 0 1 0

0 0 0 0 0 0 0

0 0 0 0 0 0 0

0 1 1 0 1 1 0

0 1 1 0 1 1 0

0 0 0 0 0 0 0

0 1 1 0 0 0 0

0 1 1 1 0 0 0

0 0 0 0 0 0 0

0 0 0 0 0 0 0

0 0 0 0 0 1 0

0 0 0 0 0 0 0

0 0 0 0 0 0 0

0 0 0 0 0 0 0

0 1 1 0 0 0 0

0 0 0 0 0 0 0

F

F1

F2

F3

F4

Figure 2. A grayscale image F and its cross-sections at levels 1,2,3,4

the component tree can be found in,11–13 the last reference also contains a discussion about time complexity of the di?erent algorithms. Let F ∈ F(E), let k ∈ Z, we denote by Ck (F ) the set of all connected components of the cross-section Fk , and we de?ne C(F ) as the union of all the sets Ck (F ) with k ∈ {kmin . . . kmax }. The elements of C(F ) are the connected components of the cross-sections of F , we will call them components. For the sake of simplicity, we suppose that two components belonging to di?erent cross-sections are always di?erent sets of points. The extension of the following de?nitions to the general case is straightforward. We de?ne the component tree T (F ) as a directed tree such that: ? the vertices of the component tree are the elements of C(F ), ? there is an arc from a component c ∈ Cj (F ) to a component c′ ∈ Ck (F ) if j = k + 1 and c ? c′ . We then say that c′ is the father of c, and we also say that c is a son of c′ . The components which have no sons are called leafs, the component which has no father is called the root , the components which have stricly more than one son are called nodes. A path in the tree from a leaf to a node or to the root is called a branch. Fig. 3 shows the component tree of the grayscale image depicted in Fig. 2. The component at level 1 is called c1 , the two components at level 2 are called c2 and c3 (according to the usual scanning order), and so on.

c7 c4 c2 c1 c5

c8 c6 c3

4 3 2 1

Figure 3. The component tree of the grayscale image of Fig. 2

3. UNION-FIND ALGORITHM FOR THE COMPONENT TREE 3.1. Disjoint Sets

The disjoint set problem consists in maintaining a collection C of disjoint subsets of a set E under the operation of union. Each set X in C is represented by a unique element of X, called the canonical element. Three operations allow to manage the collection: MakeSet(x): add the set {x} to the collection C, provided that the element x does not already belongs to a set in C. Find(x): return the canonical element of the set in C which contains x. Link(x, y): let X and Y be the two sets in C whose canonical elements are x and y respectively (x and y must be di?erent). Both sets are removed from C, their union Z = X ∪ Y is added to C and a canonical element for Z is selected and returned.

Tarjan9 proposed a very simple and very e?cient algorithm to achieve any intermixed sequence of such operations with a quasi-linear complexity. More precisely, if m denotes the number of operations and n denotes the number of elements, the worst-case complexity is Θ(mα(m, n)) where α(m, n) is a function which grows very slowly, for all practical purposes α(m, n) is never greater than four. The implementation of this algorithm is given below. The mappings ’F th’ and ’rank’ are represented by global arrays in memory. One of the key heuristic to reduce the complexity is a technique called path compression, that was used by Tarjan to reduce the cost of Find. It consists, while searching for the root of x, in setting the parent of x to be the root for all element visited along the path to the root. The other key technique, called Union by Rank, consists to always choose the root with the greatest rank to be the root representative of the union while performing the Link operation. If the two roots have the same rank, then we increase the rank of one of the root by one, and choose this root as the representative one. Union by Rank avoids creating degenerate trees, and helps keeping the size of the trees as small as possible. For a more detailed explanations and complexity analysis, see Tarjan’s paper.9 Procedure MakeSet(element x) Fth(x) ← x; rank(x) ← 0; Function element Find (element x) if (Fth(x) = x) then Fth(x) ← Find(Fth(x)); return Fth(x); Function element Link (element x, y) if (rank(x) > rank(y)) then exchange(x, y); if (rank(x) == rank(y)) then rank(y) ← rank(y) + 1; Fth(x) ← y; return y; We can illustrate the behavior of the union-?nd algorithm on the classical problem of ?nding the connected components of a graph. The algorithm is given in ?gure 3.1. For a set X, this algorithm returns a map C that gives for each pixel p, the representative C(p) of the connected component of X p belongs to. The algorithm consists essentialy in one scanning of the set X. The scanning (loop 1) processes all pixels of X in any order. For each pixel p, we ?rst ?nd a representative of the connected component it belongs to. Then, for each neighbours q of p such that q ∈ X, we ?nd a representative of the set q belongs to. If p and q are not already in the same set, that is if the two representatives di?er, p and q are linked, and one of them is chosen to be the representative of their common connected component. At the end of the scanning, a simple pass on all the elements of X (loop 2) builds the component mapping.

3.2. Quasi-linear complete component tree construction algorithm

Let us describe informally an “emergence” process that will help us to design an algorithm for the component tree. We are going to use topographical references. We can see the function as the surface of a relief with the weight of a point corresponding to its altitude. Imagine the surface completely covered by water, and that the level of water slowly decreases. Islands (maxima) appear. These islands form the leafs of the component tree. As the level of water decreases, islands will grow, building the branches of the tree. Sometimes, at a given level, several islands will merge into one connected piece. Such pieces are the nodes of the tree. We stop when

Algorithm 1: BuildConnectedComponents Data: (E, Γ) - graph Data: A set X ? E Result: C - map from X to E (connected components mapping) //Preprocessing for p ∈ X in any order do MakeSet(p);

1

begin for p ∈ X do compp = Find(p); for q ∈ Γ(p) such that q ∈ X do compq = Find(q); if (compp = compq) then compp = Link(compq, compp); end //Building the component mapping for p ∈ X do C(p) = Find(p);

2

all the water has disappeared. We can see that we have to keep track both of the connected components of a given level, and of the union of those components for varying weights. Thus, we need two Tarjan’s union-?nd implementations, one for building the union of the connected components over height, and one for building the connected components of a given altitude. The ?rst Tarjan tree is used to represent the component tree itself, the second one is to represent the connected component of a given level in the component tree. To represent a component, we use a structure called node containing the value of the altitude of the node, and the list of nodes which are sons of the current node. For building the component tree, we do not need the reverse link, that is we do not need to know the father of a given node. The algorithm is given in ?gure 2. Let us explain its behaviour. Roughly speaking, the algorithm runs through all the points of the graph once, starting with the highest ones, merging them with their neighbors of same altitude (weight), and building the tree from the parts already built at previous levels. After a preprocessing (line 1) for sorting the pixels by decreasing order of altitude and for the preparation of the two Tarjan’s implementations (line 2), we process the pixels, starting with the highest one. The highest pixels belongs to maxima of the map F , and thus, at this level, we have to ?nd some leafs of the tree; that amounts to ?nd the connected components of the highest level. The algorithm behaves exactly as the algorithm 3.1 for that case. Let us suppose that we have processed a number of levels, and thus that we have already built several parts of the component tree, that is several partial component trees. The ?rst tarjan representation is used to tell which partial component tree a pixel belongs to; the second tarjan representation is used to tell which component a pixel belongs to. Let us examine a given pixel p of the current level. We ?rst look for a canonical element of the part of the component tree the pixel p belongs to (line 3). We then look for the node of highest level in this part of the component tree, which is stored in the array subtreeRoot. This node can already be linked with other nodes of same altitude, thus we use the second Tarjan tree to look for a canonical element of this set (line 4). We then look at each neighbor q of altitude greater or equal to the one of the pixel p under examination (loop 5). Exactly as we have done for the pixel p, we search for a representative of the highest level of the part of the component tree the pixel q belongs to (lines 6-7). If the representative of p and the representative of q di?ers, that is we the two pixels are not already in the same partial component tree, we have two possibilities:

Algorithm 2: BuildComponentTree Data: (E, Γ) - graph. Data: F - map from E to Z. Result: Nn - number of nodes (of the component tree) (≤ N ). Result: nodes - array [0 . . . N ? 1] of nodes. Result: C - map from E to [0 . . . N ? 1] (component mapping). Result: Root - Root of the component tree Local: subtreeRoot - map from [0 . . . N ? 1] to [0 . . . N ? 1]. //Pre-processing Sort the points in decreasing order of value for F ; Nn ← N ; for p ∈ E do MakeSet1(p); MakeSet2(p); subtreeRoot[p] ← p; begin //Heart of the algorithm for p ∈ E in decreasing order of value for F do curCanonicalElt ← Find1(p); curNode ← Find2(subtreeRoot[curCanonicalElt]); for each (already processed) neighbor q of p with F (q) ≥ F (p) do nbrCanonicalElt ← Find1(q); nbrNode ← Find2(subtreeRoot[nbrCanonicalElt]); if (curNode = nbrNode) then if (nodes[curNode]→height == nodes[nbrNode]→height) then //Merge nbrNode and curNode tmpNode ← Link2(nbrNode,curNode); if (tmpNode == curNode) then Add the list of sons of nodes[nbrNode] to the list of sons of nodes[curNode]; else Add the list of sons of nodes[curNode] to the list of sons of nodes[nbrNode]; delete nodes[nbrNode]; nodes[nbrNode] ← nodes[curNode]; curNode ← tmpNode; Nn ← Nn ? 1; else //We have nodes[curNode]→height < nodes[nbrNode]→height nodes[curNode]→addSon(nodes[nbrNode]); curCanonicalElt ← Link1(nbrCanonicalElt, curCanonicalElt); subtreeRoot[curCanonicalElt] ← curNode; end //Post-processing Root ← subtreeRoot[Find1(Find2(0))] ; //Build the component mapping for p ∈ E do C(p) ← Find2(p);

1

2

3 4 5 6 7

8

9 10 11

12

13

? either the two representative are of same altitude; in this case, that means that these two nodes are in fact in the same component, and we have to merge the two representatives (lines 8). The merging of nodes of same altitude is done by the second Tarjan union-?nd implementation. The merging relies on the fact that the Link function always choose one of the two representatives that are to be merged as a representative of the merged set. ? either the part of the neighbor component tree, being of higher altitude, is a son of the current part. (line 9). In both cases, we have to link the two parts of the component tree, that is done using the ?rst Tarjan union implementation (line 10). We also have to keep track of the node of highest altitude (line 11). At the end of the algorithm, we have to do a post processing to return the desired result. The root of the component tree can be easily found, for instance using (lines 12) ComponentTreeRoot = subtreeRoot[Find1(Find2(0))]. The component mapping can be obtained by (loop 13) For All pixels p, C[p] = Find2(p);

3.3. Complexity analysis

The sorting of the points (line 1) can be done in linear time if the weights are integer, and in log(log(n)) for real weigths. Complete and add references Loop 2 is the preparation for the Tarjan. It is obviously linear. Line 5: Note that if the graph is symmetric, the union (Link) between two pixels is done the ?rst time one of the two pixels looks at the other as a neighbours. Thus, if we have an order of scanning of the pixels, and if the graph is symmetric, we can look only at the “already processed” neighbours. ’TRUE’ part of the ’if’ condition 8: the merging of the nodes can be done in constant time, because we can merge two lists by setting the ?rst member of one of the list to be the one that follows the last member of the other list. This requires the two list to be disjoint, which is the case (we are dealing with disjoint set). Once the merging has been done, we can delete one of the node, the one that has not been chosen to be the representative of the set. Indeed, we will not access to the content of the node again. We will only have to know to which set it belongs to, and the answer to this question is given by the ’Find’ part of the Tarjan’s algorithm. The heart of the algorithm consists in one loop (line 03), in which each pixel is examined once for itself, and n times as a neighbor. In the loop, we use two Tarjan union-?nd, of quasi-linear complexity. The merging of the nodes (’TRUE’ part of the ’if’ condition 8) is done in constant time, as adding the list of sons of nodes[neighborNode] to the list of sons of nodes[currentNode] can be done by moving a pointer. Thus the complexity of the algorithm is quasi-linear.

4. EXAMPLE

We are going to illustrate the work of the algorithm on an example. Let us look at the image of ?g. 4.a. The pixels are numbered (labeled) according to their usual lexicographical order (?g. 4.b). They are going to be examined according to their altitude (grey level), starting with the highest ones (?g. 4.c). At the begining of the seventh step, we have already constructed part of the component tree (?g. 4.b). At the end of the seventh step, we have begin to construct the ?at zone at altitude 50 (Fth2[5] = Fth2[6] = 5). At the end of the algorithm, we have completed the component tree (?g. 4.b). We can note (?g. 4.a) that Fth2 keeps track of the connected ?at zone of the component tree (the one at level 50, i.e. Fth2[5] = Fth2[6] = Fth2[7] = 5, and the one at level 10 i.e. Fth2[3] = Fth2[8] = Fth2[13] = 3). The root of Fth1 is the node 5. The highest node is the node 3 at level 10, as it is shown by subtreeRoot[5] = 3.

110 50 80

90 50 60

100 50 70 (a)

10 10 10

40 20 30

0 5 10

1 6 11

2 7 12 (b)

3 8 13

4 9 14

Figure 4. (a) original image - (b) Pixels are numbered (label) according to the usual lexicographic order, but they will be processed by decreasing grey level.

1 5 11

1 6 11

1 3 7 8 11 13 Fth1

4 9 14

0 5 10

1 6 11

2 3 7 8 12 13 Fth2 (a)

4 9 14

0 5 10

1 2 3 6 7 8 11 12 13 subtreeRoot

4 9 14

[1] 90

[11] 60

[12] 70 [10] 80 [2] 100 [0] 110

(b)

Figure 5. Begining of step 7. (a) State of the map Fth1, Fth2 and subtreeRoot. (b) Component tree already constructed

5. CONCLUSION

Wonderful work. When the union-?nd can be implemented linearly,14–16 our component tree algorithm is linear.

REFERENCES

1. P. Hanusse and P. Guillataud, “S?mantique des images par analyse dendronique,” in 8th Conf. Reconnaise sance des Formes et Intelligence Arti?cielle, 2, pp. 577–588, AFCET, (Lyon), 1992. 2. P. Guillautaud, Contribution l’analyse dendroniques des images. PhD thesis, Universit? de Bordeaux I, e 1992. 3. M. Couprie and G. Bertrand, “Topological grayscale watershed transform,” in SPIE Vision Geometry V Proceedings, 3168, pp. 136–146, 1997. 4. R. Jones, “Component trees for image ?ltering and segmentation,” in NSIP’97, 1997. 5. J. Mattes, M. Richard, and J. Demongeot, “Tree representation for image matching and object recognition,” in DGCI 99, G. Bertrand, M. Couprie, and L. Perroton, eds., LNCS, pp. 298–309, 1999. 6. P. Monasse, Morphological representation of digital images and application to registration. PhD thesis, Paris-Dauphine University, June 2000. 7. D. Wishart, “Mode analysis: A generalization of the nearest neighbor which reduces chaining e?ects,” in Numerical Taxonomy, A. Cole, ed., pp. 282–319, Academic Press, (London), 1969. 8. J. Hartigan, “Statisticak theory in clustering,” J. of Classi?cation 2, pp. 63–76, 1985. 9. R. Tarjan, “E?ciency of a good but not linear set union algorithm,” Journal of the ACM 22, pp. 215–225, 1975. 10. C. Vachier, Extraction de caract?ristiques, segmentation d’images et Morphologie Math?matique. PhD e e ? thesis, Ecole National Sup?rieure des Mines de Paris, 1995. e 11. E. Breen and R. Jones, “Attribute openings, thinnings and granulometries,” Computer Vision and Image Understanding 64, pp. 377–389, November 1996. 12. P. Salembier, A. Oliveras, and L. Garrido, “Anti-extensive connected operators for image and sequence processing,” IEEE Trans. on Image Proc. 7, pp. 555–570, April 1998.

1 5 11

5 5 5

1 3 5 8 11 13 Fth1

4 9 14

0 5 10

1 6 11

2 3 7 8 12 13 Fth2 (a)

[5] 50

4 9 14

0 5 10

1 2 3 5 7 8 11 12 13 subtreeRoot

4 9 14

[1] 90

[11] 60

[2] 100 [0] 110 [12] 70 [10] 80

(b)

Figure 6. End of step 7. (a) State of the map Fth1, Fth2 and subtreeRoot. (b) Component tree already constructed

1 5 11

5 5 5

5 5 5 5 5 5 Fth1

9 5 5

0 5 10

1 5 11

2 3 5 3 12 3 Fth2 (a)

4 9 14

0 3 10

1 2 3 6 7 8 11 12 13 subtreeRoot

4 3 14

[3] 10 [5] 50 [1] 90 [9] 20

[11] 60[4] 40[14] 30

[10] 80 [2] 100 [0] 110[12] 70

(b)

Figure 7. End of algorithm. (a) State of the map Fth1, Fth2 and subtreeRoot. (b) Component tree

13. J. Mattes and J. Demongeot, “E?cient algorithms to implement the con?nement tree,” in 9th Conf. on D.G.C.I., LNCS 1953, pp. 392–405, Springer Verlag, 2000. 14. H. Gabow and R. Tarjan, “A linear-time algorithm for a special case of disjoint set union,” J. Comput. System Sci. 30, pp. 209–221, 1984. 15. M. Dillencourt, H. Samet, and M. Tamminen, “A general approach to connected-component labeling for arbitrary image representations,” J. Assoc. Comput. Mach. 39(2), pp. 253–280, 1992. 16. J. Gustedt, “E?cient union-?nd for planar graphs and other sparse graph classes,” Theoretical Computer Science 3, pp. 123–141, August 1998.

- A quasi-Monte Carlo algorithm for the global illumination in the radiosity setting
- Quasi-linear algorithms for the topological watershed
- THE CONSTRAINT PROPAGATION ALGORITHM FOR DETERMINING THE STABILITY MARGIN OF LINEAR PARAMET
- A near-linear algorithm for the planar 2-center problem
- A linear tree edit distance algorithm for similar ordered trees
- Nonlinear system modeling and predictive control using the RBF nets-based quasi-linear ARX model
- A forward--backward stochastic algorithm for quasi-linear PDEs
- A Linear Time Algorithm for the Minimum Spanning Tree Problem on a Planar Graph
- The Ellipsoid Algorithm for Linear Programming
- The Beauty and Beast Algorithm Quasi-Linear Incremental Tests of

- Quasi-linear algorithm for the component tree
- 文秘知识-学校科研成果与荣誉称号奖励办法 精品
- 施工现场防台防汛检查表
- 9小学教职工代表大会活动方案
- 白羊座男和处女座女配不配
- 行业趋势预测-2018-2023年中国捻丝机行业发展趋势预测与投资咨询报告-目录
- 青年教师师德建设演讲稿范文：我选择,我热爱
- 世界大学生三对三篮球联赛传切配合分析
- 【最新】部编版2019年秋三年级语文上册：课后作业 18 富饶的西沙群岛(精品)
- 《幼儿教育》-幼儿园小班数学教案：小鸟的家精选
- 实用企业代理合同范本
- 举例说明生活中都有哪些属于美拉德反应
- 行业趋势预测-2018-2023年中国弹力丝假捻变形机行业发展趋势预测与投资咨询报告-目录
- 鹿邑县金峰种植专业合作社企业信用报告-天眼查
- 2016年中考备考作文复*：考试并没有结束
- 门诊护士的语言和品德修养_论文
- 金花葵加工生产项目可行性研究报告立项申请报告模板
- 县第二幼儿园(大一班)“有质量的户外两小时”活动设计方案
- 《道路勘测设计》纵断面设计
- 社会调查 大学生对恋爱态度
- 牛津译林版七年级下英语期末考试专题练*—词汇

- 测试技术课程课后*题答案
- 减肥中药方子
- 四级高频词组短语(附例句)
- 玉溪恒丰寄售有限公司企业信用报告-天眼查
- 夏季工程服项目可行性研究报告(目录)
- 19 应急预案及关键流程演练记录
- 天天酷跑如何摇出魔力宝贝方法心得分享
- 工作反思报告范文3篇
- 细旦锦纶66弹力丝生产工艺探讨.pdf 126KB
- 建党90周年征文 回顾90周年,党走过的辉煌
- 桥梁工程课件第2篇第三章混凝土简支梁桥的计算
- 详解心悸症状及日常饮食的搭配和宜忌
- 2019年南通中小学春节开学时间怎么安排2019年南通中小学暑假从什么时候开始放
- 郑州小区停车管理办法全文
- 语言是护士素养的试金石
- 读《黄继光》有感_六年级作文_1
- 华为项目管理模板
- 2012年一月份人力资源管理师二级考试重点和考试技巧
- n钢筋混凝土圆管涵工程数量表
- 2019年寒假大学生工程测量社会实践报告
- 中国证券监督管理委员会四川监管局关于张杰证券公司分支机构负责
- 论九三学社树立和践行社会主义核心价值体系的实践途径
- 一年级上册数学课件-第7单元认识钟表｜人教新课标(2018秋) (共15张PPT)
- JB-QG-OZH4800火灾报警控制器立柜(联动型)
- hdmi线可以接吗
- 九年级物理全册 14.2 热机的效率同步练* (新版)新人教版
- 20XX年父亲节祝福短信精选_4
- 令狐冲的性格特点形象
- 我的双休日邢爱学
- 事业励志语录句子大全
- 海明威短篇小说中的尼克形象
- 福建省2017年临床医学检验技术中级相关专业知识试题
- 2016高考英语一轮复*优质课件：高考英语重点词汇(共47张PPT)教材
- 弥勒菩萨所问本愿经 西晋三藏竺法护译
- 高考数学一轮总复*第7章不等式推理与证明第4节基本不等式及其应用模拟创新题理练*
- 六年级做快乐的自己优秀作文600字精选
- 数学：图形的运动课后反思
- 我爱我家主题队会
- 税法第1章练*及答案
- 中国全站仪市场供需预测及发展趋势研究报告目录
- 徒手心肺复苏术ppt课件
- 宝宝不爱吃饭如何让宝宝顺利接受辅食