Poj2513 colored sticks (trie tree + parallel query set + Euler path)

Source: Internet
Author: User

The question is to give a bunch of wooden sticks, each of which has two endpoints painted with color, ask whether the pile of wooden sticks can be connected to each other to form a big wooden stick, the conditions of the connection is: if two sticks have the same color endpoint, they can be connected by the same color endpoint. For example:

Blue Red
Red Violet
Cyan blue
Blue Magenta
Magenta cyan
Blue magenta (magenta Cyan) (cyan blue) (blue red) (Red violet ).
It is not difficult to find that, in the final composition of the big wooden stick, except for the first and last two endpoints, the number of colors may be odd, and the number of other colors must be even, because each color in the middle is paired. If a graph is used to indicate that each color is a vertex, at most two vertices have an odd degree. Of course, this condition is not enough, for example, the following example:

Blue Red
Red blue
Cyan black
Black cyan

Although the degrees of all colors are even, they still cannot meet the requirements. In this case, the graph is not connected. Therefore, another condition is that the graph must be connected.
Is it like the Euler's path? Actually, it is the Euler's path. As a result, the sufficient and necessary condition for undirected graph G to have Euler's path is: G connectivity, and G has only two odd vertices (they are the two ends of the Euler's path ). Now that we have reached the conclusion, is it possible to directly establish the adjacent matrix? In fact, it is not necessary. The focus of the adjacent matrix is to save the edge. If we only judge whether it is an Euler path, we do not need to store the edge information because we only care about two points: the degree of vertex, and whether the graph is connected. You can use a set to determine whether a graph is connected. Each set represents a connected subgraph (that is, any two vertices in the set are connected). At the beginning, each vertex forms a set. Then, each time an edge is read, you can perform the following operations: first update the degree of the two vertices of the edge, and then merge the sets of the two vertices, then the edge can be discarded (no need to save it) and read the next edge. After reading all the edges, you can check the conditions and count the number of odd vertices. Then, if the graph is connected, all the vertices will belong to the same set.

The set can be used to query the set. The main operation is to determine the set to which the element belongs to find and merge the set union. Check the two implementation methods, namely, chunk-chain and tree-type, and briefly describe the advantages and disadvantages of the two implementation methods. The chain find operation is fast, the complexity O (1), and the Union time is related to the chain length; the time of the tree find operation is related to the height of the tree. The union operation is O (1 ). My implementation uses tree.

In addition, this topic vertex is not 0, 1, 2... this type of number type, but string type, because the data size is large, so it needs to be more efficient string search. You can use hash or trie tree. I use a trie tree that is dynamically created.

# Include <stdio. h> # include <stdlib. h> # include <string. h> typedef struct tnode {struct tnode * Next [26]; // The Child int degree of the node in the trie tree; struct tnode * representation_element; // The representative element of the Set} node; node * root; // trie root node * union_node; // If the graph is connected, all nodes should point to the same element (that is, a collection ), save this representation of the Meta int odd_count; // Number of odd-degree nodes node * create_node (char value, node * parent) {node * node = (node *) malloc (sizeof (node); memset (node-> next, 0, sizeof (node-> next )); Node-> degree =-1; node-> representation_element = node; // At the beginning, a node forms a set. The element of the set is of course its own. If (parent! = NULL) {int I = (INT) (value-'A'); node ** next = parent-> next; If (next [I] = NULL) {next [I] = node;} return node;}/*** search. If no node is found, the trie Tree node */node * search_or_insert (char * Str) is dynamically created) {Int J = 0; char C; node * current_node = root; while (C = STR [J ++])! = '\ 0') {int I = (INT) (C-'A'); If (current_node-> next [I] = NULL) {current_node = create_node (C, current_node);} else {current_node = current_node-> next [I] ;}} if (current_node-> degree =-1) {current_node-> degree = 1;} else {current_node-> degree ++;} return current_node;}/*** set merging */void union_set (node * first_node, node * second_node) {While (first_node-> representation_element! = First_node) {// find the corresponding representative Yuan. If the representative yuan of a node is equal to the node itself, it indicates the Yuan first_node = first_node-> representation_element ;} while (second_node-> representation_element! = Second_node) {second_node = second_node-> representation_element;} If (first_node = second_node) {// This Is A set. Return it directly;} second_node-> representation_element = first_node; // change the representative element of second_node to first_node} void go_get_result (node * node) {// pre-order traversal if (node = NULL) {return;} int degree; if (node! = Root & (degree = node-> degree )! =-1) {If (degree & 1) = 1) {odd_count ++; If (odd_count = 3) {// according to the condition of the Euler's path ..... too many vertices in an odd number; printf ("impossible \ n"); exit (0); }}if (union_node = NULL) {union_node = node-> representation_element ;} else {node * current_node = node; while (current_node-> representation_element! = Current_node) {current_node = current_node-> representation_element;} If (union_node! = Current_node) {// do not connect printf ("impossible \ n"); exit (0) ;}} node ** next = node-> next; int I = 0; for (; I <26; I ++) {go_get_result (next [I]) ;}// free (node) ;}int main (void) {char first [11]; char second [11]; root = create_node ('A', null); union_node = NULL; odd_count = 0; while (scanf ("% S % s", first, second )! = EOF) {node * first_node = search_or_insert (first); node * second_node = search_or_insert (second); union_set (first_node, second_node ); // merge the set according to the rod} go_get_result (Root); printf ("Possible \ n"); // free to release the memory .. return 0 ;}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.