Analysis of the problems related to the end of October disjoint-set

For the first time the girls training analysis related questions:

The first is the first question:

How Many Tables

Today is Ignatius' birthday. He invites a lot of friends. Now it's dinner time. Ignatius wants to know how many tables he needs at least. You have to notice that not all the friends know each other, and all the friends do not want to stay with strangers.

One important rule for this problem is that if I tell you A knows B, and B knows C, that means A, B, C know each other, so they can stay in one table.

For example: If I tell you A knows B, B knows C, and D knows E, so A, B, C can stay in one table, and D, E have to stay in the other one. So Ignatius needs 2 tables at least.
 
This is a disjoint-set templates questions, but I disjoint-set relatively unknown, so read the topic, looking for a good template for a while before using the template, I realize that mastery of disjoint-set is very weak. My disjoint-set template based learning exercises was a change of: HDU-1233 or expedite project (minimum spanning tree & disjoint-set)
Copy the code
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <algorithm>
 5 #include <math.h>
 6 
 7 using namespace std;
 8 
 9 int pre[1001];
10 struct node{
11     int x;
12     int y;
13 }a[1001];
14 
15 int find(int x){
16     int r=x;
17     while(pre[r]!=r)
18         r=pre[r];
19     return r;
20 }
21 
22 int main(){
23     int N,M,i,num;
24     int T;
25     scanf("%d",&T);
26     while(T--){
27         scanf("%d%d",&N,&M);//N表示朋友个数,M表示关系条数
28 num = N; // N n between friends sitting up tables
29 for (i = 1; i <= N; i ++) // pre array initialization 
30 pre [I] = I; 
31 is for (I =. 1; I <= M; I ++) { 
32 Scanf ( "% D% D ", a & [I] .x, & a [I] .y); 
33 is here connected // friends know 
34 is int Find B = (a [I] .x); 
35 C int = Find (a [I ] .y); 
36 IF (B = C) {! 
37 [pre [C] = B; 
38 is num--; 
39} 
40} 
41 is the printf ( "% D \ n-", NUM); // for output formats have variable 
42 is} 
43 is return 0; 
44 is}
Copy the code

So I decided to brush and check the water problem set, you can first learn she said Tuesday brush water problem, then gradually increase the difficulty, to build their confidence.

The following is a water theme A:

A - Smooth Traffic Project   HDU 1232 (roughly meaning of the title)

A provincial survey of urban traffic, urban roads to get existing tables, the table lists the cities and towns each road directly connected. Target provincial government "Smooth Traffic Project" is to make the province between any two towns can implement traffic (but not necessarily directly connected to the road, as long as you can reach each other indirectly through road). Minimum asked how many roads also need to build? 

Input

Test input contains several test cases. Each test case is given row of the first two positive integers, are the number of towns N (<1000) and road number M; M rows corresponding to the next M path, each row is given a pair of positive integers, respectively, the number two towns in direct communication path. For simplicity, the town numbered from 1 to N. 
Note: You can communicate a number of roads between the two cities,

emmm this very obvious water problem, that is, sets of templates, but let me briefly understand the general idea of ​​this algorithm. Simple question, simple A.
 
Copy the code
#Include. 1 <the iostream> 
 2 #include <stdio.h> 
 . 3 
 . 4 pre int [1001]; 
 . 5 
 . 6 Find int (int X) {// find the root node 
 . 7 int X = R & lt; 
 . 8 the while (pre [R & lt]! = r) // return the root node 
 . 9 = R & lt pre [R & lt]; 
10 int X = I, J; 
!. 11 the while (I = R & lt) {// path compressor 
12 j = pre [i]; // change the upper before recording a temporary variable j at its value 
13 pre [i] = r; // put his superiors directly to the root node, the ultimate Boss 
14 I = j; // subsequently to change his original superior to its parent ultimate Boss 
15} 
16 return R & lt; 
. 17} 
18 is 
. 19 the Join void (int a, int b) { 
20 is // determines whether a and b are in communication 
21 // If communication has been, you can not control 
22 // If not connected, it the communication branch in which they are combined to 
23 int fx = find (a) ;
Find int = FY 24 (B);
46         printf("%d\n",ans); 
25 IF (! FX = FY)
26 pre [fx] = fy; // not optimized, the resulting tree may be deformed tree 
27} 
28 
29 int main () { 
30 int n-; 
31 is the while (Scanf ( "% D", & n-) && n-= 0!) { 
32 int m, I, a, B, ANS; 
33 is for (I =. 1; I <= n-; I ++) // initialization pre array 
34 is pre [I] = I; 
35 // Memset (pre, 0 , pre + n-); 
36 Scanf ( "% D", & m); 
37 [for (I =. 1; I <= m; I ++) { 
38 is Scanf ( "% D% D", & A, & B); 
39 the Join ( A, B); 
40} 
41 is for (ANS = 0, I =. 1; I <= n-; I ++) { 
42 is IF (pre [I] == I) 
43 is ANS ++; 
44 is} 
45 ans- =. 1; 
47} 
return 0 48; 
49}
Copy the code

Next came

B - ? Little hope maze | IT A Tree Is is HDU 1272 (roughly meaning of the questions) 

Last Gardon maze castle little hope to play for a long time (see Problem B), and now she wanted to design a maze Gardon to let go. But she maze design ideas are not the same, she thought first of all of the channels should be two-way communication, that is if there is a passage room A and B, then both went to the room from the room A through B it can also be it went through the room a from the room B, to raise the difficulty, any small hope hope the two rooms has one and only one path can communicate (unless go back now). Little hope now her design to you, let you help her determine whether the design of her design ideas. For example the following example, the first two are eligible, but there are two ways to the final arrival 8 from 5. 

Input

Input data comprises a plurality of sets, each set of data is an integer of 00 to the end of the list, indicates the number of two rooms a channel connection. No room is at least 1 and not more than 100,000. A blank line between each two sets of data. 
Two end in the entire file 1. 

 

In fact, I think this problem will start to see some faint, like training inside that title, but also need to look longer, in order to use the correct template. It seems my understanding of the disjoint-set is not enough. . . .

And this question was wrong several times, minor errors in the output of this you do not need to mention, is wrong on the order of some algorithms, the template is not cooked enough cooked ah!

The final AC Code:

Copy the code
#Include. 1 <the iostream> 
 2 #include <stdio.h> 
 . 3 the using namespace STD; 
 . 4 
 . 5 const int N = 100010; 
 . 6 pre int [N], S; 
 . 7 NUM int [N], V [N]; 
 . 8 
 . 9 void the Init () { 
10 for (int I =. 1; I <= N; I ++) { 
. 11 pre [I] = I; 
12 is V [I] = NUM [I] =. 1; // V [] recording state from is beginning. 1 
13 is} 
14} 
15 Find int (int X) {// find the root node 
16 int X = R & lt; 
. 17 the while (! pre [R & lt] = R & lt) // return the root node 
18 r = pre [r]; 
. 19 / int * X = I, J; 
20 is the while (! I = R & lt) {// compression path 
21 j = pre [i]; // j recorded at its value before the temporary variable to change the upper 
22 pre [i ] = r; // put his superiors directly to the root node, the ultimate Boss 
23 is I = J; // Next to change their original higher its superior ultimate Boss
} * 24/ 
25 return R & lt; 
26 is} 
27 
28 int the Join (int a, int b) { 
29 // determines whether a and b are in communication 
30 FX int = Find (a); 
31 is int FY = Find (b); 
32 if (fx == fy) {// if communication at this time so that it will produce the tree circuit 
33 is return. 1; 
34 is} 
35 the else { 
36 pre [FY] = FX; // do not belong to the same two rooms as a connection tree 
37 [NUM [FX] + = NUM [FY]; 
38 is S = NUM [FX]; 
39 return 0; 
40 // not optimized, the resulting tree may be deformed tree 
41 is} 
42 is} 
43 is 
44 is int main () { 
45 int I, A, B; 
46 is the while (Scanf ( "% D% D", & A, & B) && (A = -. 1 || B = -. 1)!!) { 
47 the Init (); 
48 IF ( a == 0 && b == 0) {// Analyzing empty tree where
49             printf("Yes\n");
50             continue;
51         }
52         int ok=join(a,b),n=v[a]+v[b];  //ok记录是否存在环,n记录节点总数  
53         v[a]=v[b]=0;
54         for(i=2;i<=N;i++){
55             scanf("%d%d",&a,&b);
56             if(a==0&&b==0)
57                 break;
58             n+=(v[a]+v[b]);
59             v[a]=v[b]=0;
60             ok+=join(a,b);
61         }
62         if(ok)
63             printf("No\n");
64         else{
65             if(s==n)
66                 printf("Yes\n");
67             else
68                 printf("No\n");
69         }
70     }
71     return 0;
72 }
Copy the code

 

For summary disjoint-set of the first here, but also greatly enhance the learning efforts.

Guess you like

Origin www.cnblogs.com/sanluohubo/p/11768523.html