POJ 1182 http://poj.org/problem?id=1182
Analysis: The main idea is very clear, is to find out the number of lies, the title of the lie required to have three
① the current words clash with some of the true words in front, it is a lie;
② the current words of x or y is greater than N, is a lie;
③ current words mean x eats x, is a lie.
② and ③ very good judgment, the most difficult is the lie condition ①!! It says that there are three kinds of animals a,b,c; A-->b-->c-->a (a eat B, B eat c,c and eat a), form a ring; however, we have no way to give the animals (numbers instead of) exactly what kind. Then, since these three animals form a ring, then we combine all the associated elements into a single set. There is a representative element in the collection (which may also be called the root element). Differentiate them by their relationship to the root element. Relation[i] = 0 means the same as the root element relation[i] = 1 is the class that eats the root element, relation[i] = 2 is a class that is eaten by the root element. The relationship between elements and the root element clearly divides them into three categories, without having to indicate exactly which category.
#include <iostream>#include<cstdio>#include<string.h>using namespacestd;intN, M, d, X, Y, FX, FY, SUM, pre[50010], relation[50010];//Initializing a collectionvoidinit () { for(inti =1; I <= N; i++) {Pre[i]=i; Relation[i]=0; }}intFindintA//finding the ultimate Representative element{ intI, J; I=A; if(Pre[a] = =a)returnA; Else{J=Pre[i]; Pre[i]= Find (j);//by way of recursionRelation[i] = (Relation[i] + relation[j])%3; //this place is key. The edge looks for the root element, and the edge draws the relationship to the root element. This through//the relationship between the element and the Father element is also found in the relationship between the father element and the root element. //This relationship I was enumerated after summarizing the following there is the process of rollout. } returnpre[a];}//in this I wrote two merged function Union1,union2, mainly because d = 1 o'clock and d = 2 o'clock//The equation for relation is different, and the equation is pushed to the process below.voidUnion1 (intAintb) {PRE[FX]=fy; RELATION[FX]= (3+ (Relation[b]-relation[a]))%3;}voidUnion2 (intAintb) {PRE[FX]=fy; RELATION[FX]= (3+ (Relation[b]-relation[a]) +1) %3;}intMain () {scanf ("%d%d", &n, &m); Init (); Sum=0; for(inti =1; I <= m; i++) {scanf ("%d%d%d", &d, &x, &y); if(X > N | | y > N | | (d = =2&& x = =y)) {sum++; Continue; } FX=find (x); FY=find (y); //if the root element of x and Y is different, it means that at least one of the elements is no longer in the collection and the elements need to be merged if(FX! =FY) { if(d = =1) Union1 (x, y); ElseUnion2 (x, y); } //when the root element of x and Y is the same, it means that they are all in the collection! This makes the job critical!! //It is necessary to judge whether this is the relationship between the given and the existence of the relationship is conflict, if the conflict, lie more than one! Else if(FX = =FY) { if(d = =1) { if(Relation[x]! =relation[y]) sum++; } if(d = =2) { if(Relation[x]! = (relation[y]+1) %3) Sum++; }}} printf ("%d\n", sum); return 0;}
View Code
Union2 RELATION[FX] = (3 + (Relation[b]-relation[a]) + 1)% 3;
2
x and root element Relationship between the FX |
y and the root element fy |
fx relationship with FY |
relation[b]-relation[a] |
0 ; |
0 |
1 |
0 |
1 |
0 |
0 |
-1 |
2 |
0 |
2 |
-2 |
0 |
1 |
2 |
1 |
1 |
1 |
1 | Td>0
2 |
1 |
0 |
-1 |
0 |
2 |
0 |
2 |
1 |
2 |
2 |
1 |
2 |
1 |
0 |
Union1 RELATION[FX] = (3 + (RELATION[B)-relation[a])% 3;
x relationship to the root element fx |
Y relationship to the root element fy |
The relationship between FX and FY |
RELATION[B]-Relation[a] |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
2 |
2 |
2 |
1 |
0 |
2 |
-1 |
1 |
1 |
0 |
0 |
1 |
2 |
1 |
1 |
2 |
0 |
1 |
-2 |
2 |
1 |
2 |
-1 |
2 |
2 |
0 |
0 |
Find Relation[i] = (Relation[i] + relation[j])% 3;
The relationship between element I and Father Element J |
The relationship between the J element and the root element |
The relationship between element I and root element |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
2 |
2 |
1 |
0 |
1 |
1 |
1 |
2 |
1 |
2 |
0 |
2 |
0 |
2 |
2 |
1 |
0 |
2 |
2 |
1 |
POJ2492 is similar to this problem, he just will a,b,c three kinds of animals into male, female two species. Relation may be homogeneous or heterogeneous. If a pair is the same, then the exception is indicated. Relation relationship: Find Find when relation[i] = (Relation[i] + relation[j])% 2; Merge Relation[fx] = (Relation[a] + relation[b] + 1)% 2.
#include <iostream>#include<cstdio>#include<string.h>using namespacestd;intN, m, x, y, flag, pre[ .], relation[ .];voidinit () { for(inti =1; I <= N; i++) {Pre[i]=1; Relation[i]=1; }}intFindintFA) { intR, I, J; R= A; i =A; if(Pre[a] = =a)returnA; Else{J=Pre[i]; Pre[i]=find (j); Relation[i]= (Relation[i] + relation[j])%2; } returnpre[a];}voidUnion (intAintb) { intFX =find (a); intFY =find (b); if(FX! =fy) pre[fx]=fy; RELATION[FX]= (Relation[a] + relation[b] +1) %2;}intMain () {intT, Num; CIN >>T; Num=0; while(Num <t) {scanf ("%d%d", &n, &m); Init (); Flag=0; for(inti =1; I <= m; i++) {scanf ("%d%d", &x, &y); if(Flag = =1)Continue; intFX =find (x); intFY =find (y); if(FX! =FY) Union (x, y); Else if(FX = =FY) { if(Relation[x] = =Relation[y]) {Flag=1; printf ("rela%d = = rela%d\n", x, y); }}} printf ("Scenario #%d:\n", ++num); if(Flag = =1) printf ("Suspicious bugs found!\n\n"); Else if(Flag = =0) printf ("No Suspicious bugs found!\n\n"); } return 0;}
View Code
poj1182 food chain (Type and collection) detailed