// The neckcycle (Necklace) // PC/ultraviolet A IDs: 111002/10054, popularity: B, success rate: Low Level: 3 // verdict: accepted // submission date: 2011-10-04 // UV Run Time: 0.556 S // copyright (c) 2011, Qiu. Metaphysis # Yeah dot net // [Problem description] // my little sister had a beautiful neck1_made of colorful beads. each two // successive beads in the neckdeskshared a common color at their meeting point, // as shown below: /// ---- green -- red ---- red -- white ---- white -- green ---- green -- blue ---- // but, alas! One day, the neck1_tore and the beads were scattered all over the // floor. my sister did her best to pick up all the beads, but she is not sure // whether she found them all. now she has come to me for help. she wants to know // whether it is possible to make a neck1_using all the beads she has in the // same way that her original neck1_was made. if so, how can the beads be so // arranged? /// Write a program to solve the problem. /// [input] // the first line of the input contains the integer T, giving the number of test // cases. the first line of each test case contains an integer N (5 ≤ n ≤ 1,000) // giving the number of beads my sister found. each of the next n lines contains // two integers describing the colors of a bead. colors are represented by integers // ranging from 1 to 50. /// [Output] // for each test case, print the test case number as shown in the sample output. // If reconstruction is impossible, print the sentence "some beads may be lost" // on a line by itself. otherwise, print n lines, each with a single bead description // such that for 1 ≤ I ≤ n −1, the second integer on line I must be the same as // The first integer on line I + 1. additionally, the second I Nteger on line N // must be equal to the first integer on line 1. there may be allowed solutions, any // one of which is acceptable. /// print a blank line between two successive test cases. /// [sample input] // 2 // 5 // 1 2 // 2 3 // 3 4 // 4 5 // 5 6 // 5 // 2 // 1 // 2 2 2 // 3 4 // 3 1 // 2 4 // [sample output] // case #1 // some beads may be lost /// /case #2 // 2 1 // 1 3 // 3 4 // 4 2 // 2 2 /// [solution] // if the color of both ends of the beads is as the top Point, the bead itself is regarded as an edge, then this question can be modeled as an Euler Loop problem. You need to determine whether the vertex degree is an even number. If they are an even number, you can only include the Euler's loop. Then, you can determine whether the graph is connected. If both conditions are met, then there must be a // Euler loop, just find out. You can use the width or depth traversal to determine the graph connectivity. You can also use non-intersection merging/Data Structure Query/(and query set) for determination. Because this question has a lot of input and output, you can use "\ n" instead of Endl to reduce the running time when the output is changed. // the running time is 1.668 s when Endl is used, because Endl needs to immediately refresh the output cache after the output line break, it takes a lot of time ). During the submission, we also found that the test data in the UVA onlinejudge is connected graphs, and the steps to determine whether it is a connected graph can be omitted! Oh, the test data is really weak ...... # include <iostream> # include <cstring> # include <queue> using namespace STD; # define maxv 50 vector <int> edges [maxv + 1]; int connected [maxv + 1] [maxv + 1]; int degree [maxv + 1]; int parent [maxv + 1]; // query a collection, adopts path compression optimization. Int find (int x) {return (parent [x] = x )? X: (parent [x] = find (parent [x]);} // output the Euler loop. The idea is to first find a ring and then delete it, start from the next starting point and connect these rings to the public/common endpoint to form an Euler loop. It can be implemented using recursion. Void eulerian_cycle (INT begin) {for (int to = 1; to <= maxv; To ++) if (connected [begin] [to]) {connected [begin] [to] --; connected [to] [begin] --; eulerian_cycle (); cout <to <"" <begin <"\ n" ;}}// use the width traversal to determine whether the graph is connected. Bool breadth_first_search (INT begin) {bool discovered [maxv + 1]; // The number of edges is 0, indicating that the color is not displayed and marked as traversed. For (INT c = 1; C <= maxv; C ++) discovered [c] = (edges [C]. size () = 0); queue <int> q; q. push (BEGIN); While (! Q. empty () {int vertex = Q. front (); q. pop (); For (int v = 0; v <edges [vertex]. size (); V ++) if (discovered [edges [vertex] [v] = false) {q. push (edges [vertex] [v]); discovered [edges [vertex] [v] = true ;}// if no vertex is found, the graph is not connected. For (INT c = 1; C <= maxv; C ++) if (discovered [c] = false) return true; return false;} void solve_by_breadth_first_search (void) {int number = 1, cases; // current test sequence number and number of test cases. Int N; // Number of beads. Int cleft, cright; // the color of the left and right sides of the beads. Cin> cases; while (cases --) {memset (connected, 0, sizeof (connected); For (INT c = 1; C <= maxv; C ++) edges [C]. clear (); // create an undirected graph and obtain the Euler's loop. Cin> N; For (INT c = 1; C <= N; C ++) {CIN> cleft> cright; edges [cleft]. push_back (cright); edges [cright]. push_back (cleft); connected [cleft] [cright] ++; connected [cright] [cleft] ++;} // determines whether the graph is connected, you can determine by traversing the width first. Find a starting point to traverse. Int begin = 1; while (! Edges [begin]. Size () Begin ++; bool impossible = breadth_first_search (BEGIN); // If the graph can be connected, the degree of determination is even. If (! Impossible) {for (INT c = 1; C <= maxv; C ++) if (edges [C]. size () & 1) {impossible = true; break ;}} cout <"case #" <number ++ <"\ n"; if (impossible) cout <"some beads may be lost \ n" <Endl; elseeulerian_cycle (BEGIN); If (cases) cout <"\ n ";}} // use and query the set to solve the problem. Void solve_by_union_find (void) {int number = 1, cases; // current test sequence number and number of test cases. Int N; // Number of beads. Int cleft, cright; // the color of the left and right sides of the beads. Cin> cases; while (cases --) {memset (connected, 0, sizeof (connected); memset (degree, 0, sizeof (degree )); for (INT c = 1; C <= maxv; C ++) parent [c] = C; CIN> N; For (INT c = 1; C <= N; c ++) {CIN> cleft> cright; connected [cleft] [cright] ++; connected [cright] [cleft] ++; degree [cleft] ++; degree [cright] ++; // check whether the cleft and cright are in the same set. If they are not in the same set, execute // and perform the operation. Int pleft = find (cleft); int pright = find (cright); If (pleft! = Pright) parent [pleft] = pright;} bool impossible = false; // determine whether the graph is connected. First, find a vertex whose degree is not 0 as the start point. Int begin = 1; while (! Degree [begin]) Begin ++; int tparent = find (BEGIN); For (INT c = 1 + begin; C <= maxv; C ++) if (degree [c] & find (c )! = Tparent) {impossible = true; break;} // determines whether the vertices have even degrees. If (! Impossible) {for (INT c = 1; C <= maxv; C ++) if (degree [c] & 1) {impossible = true; break ;}} cout <"case #" <number ++ <"\ n"; if (impossible) cout <"some beads may be lost \ n "; elseeulerian_cycle (BEGIN); If (cases) cout <"\ n" ;}} int main (int ac, char * AV []) {// use the width-first traversal to determine if the graph is connected, and the ultraviolet A rt is 0.556 S. Solve_by_breadth_first_search (); // use and check the set to determine whether the graph is connected. The image rt is 0.560 S. // Solve_by_union_find (); Return 0 ;}