This is the last question of the query set. It is said that this is also the most classic question. I often train the previous questions, and the idea of this question is very fast.
You can figure it out. You only need to add a message to each node to indicate the distance from the root node, and the distance is in a 3-loop manner.
Ensure that the distance change is correct during merging. In addition, merging can be performed in two cases: merging at the same distance and merging at different distances.
They correspond to operations 1 and 2 in the topic description.
The key is to face the changes in the distance from the nDis array in FindSet. The previous error has been written, wa several times, or
I caught a glance at my teammate code and found that I wrote an error here... The update of the current distance is equal to the current distance plus the previous one.
The distance between nodes is modeled as 3, which is similar to the update method of the previous questions.
This method places the relevant nodes in a query set and adds other information to each node to describe other relationships,
It is indeed effective... The query set is applied to the data structure of the non-intersecting set. It seems that at some time it is quite useful...
The Code is as follows:
# Include <stdio. h>
# Include <string. h>
# Include <algorithm>
Using namespace std;
Const int MAX = 50010;
Int nN, nK;
Int nSets [MAX];
Int nDis [MAX];
Void MakeSets (int nN)
{
For (int I = 1; I <= nN; ++ I)
{
NSets [I] = I;
NDis [I] = 0;
}
}
Int FindSet (int nI)
{
If (nSets [nI]! = NI)
{
Int nPre = nSets [nI];
NSets [nI] = FindSet (nSets [nI]);
NDis [nI] = (nDis [nPre] + nDis [nI]) % 3;
}
Return nSets [nI];
}
Int main ()
{
Int nAns = 0;
Int nOper, nX, nY;
Scanf ("% d", & nN, & nK );
MakeSets (nN );
While (nK --)
{
Scanf ("% d", & nOper, & nX, & nY );
If (nX> nN | nY> nN | nOper = 2 & nX = nY)
{
++ NAns;
}
Else
{
If (nOper = 1)
{
Int nA = FindSet (nX );
Int nB = FindSet (nY );
If (nA = nB)
{
If (nDis [nX]! = NDis [nY])
{
++ NAns;
}
}
Else
{
NSets [nB] = nA;
NDis [nB] = (nDis [nX]-nDis [nY] + 3) % 3;
}
}
Else
{
Int nA = FindSet (nX );
Int nB = FindSet (nY );
If (nA = nB)
{
If (nDis [nX] + 1) % 3! = NDis [nY])
{
++ NAns;
}
}
Else
{
NSets [nB] = nA;
NDis [nB] = (nDis [nX] + 1-nDis [nY] + 3) % 3;
}
}
}
}
Printf ("% d \ n", nAns );
Return 0;
}