Original question:
A war is being leads between-countries, a and B. As a loyal citizen of C, you decide to help your countrys espionage by attending the Peace-talks taking place these days ( Incognito, of course). There is n people at the talks (not including you), but don't know which person belongs to which country. Can see people talking to all other, and through observing their behaviour during their occasional one-to-one convers ations, you can guess if they is friends or enemies. In fact-your country would need to know was whether certain pairs of people is from the same country, or they was ENE Mies. You could receive such questions from Cs government even during the peace-talks, and you had to give replies on the basis O F your observations so far. Fortunately nobody talks to you, as nobody pays attention to your humble appearance.
Now, more formally, consider a black box with the following operations:
Setfriends (x, y)
Setenemies (x, y)
Arefriends (x, y)
Areenemies (x, y)
shows that x and Y is from the same country
shows that x and y is from different countries
Returns True if you is sure that X and Y is friends
Returns True if you is sure that X and Y is enemies
The first and operations should signal an error if they contradict with your former knowledge. The Relations ' friends ' (denoted By∼) and ' enemies ' (denoted by∗) have the following properties:
∼is an equivalence relation, i.e.
1. If x∼y and Y∼z then X∼z (The Friends of my friends is my friends as well.
2. If X∼y then y∼x (friendship is mutual.)
3. X∼x (Everyone is a friend of himself.)
∗is Symmetric and Irreflexive
1. If X∗y then y∗x (hatred is mutual.)
2. Not X∗x (Nobody was an enemy of himself.)
Also
1. If x∗y and Y∗z then x∼z (A common enemy makes, people friends.
2. If x∼y and Y∗z then X∗z (an enemy of a friend are an enemy.
Operations setfriends (x, y) and setenemies (x, y) must preserve these properties.
Input
The first line contains a single integer, N, the number of people.
Each of the following lines contains a triple of integers, Cxy, where c is the code of the operation:
c = 1,
c = 2,
c = 3,
c = 4,
Setfriends
Setenemies
Arefriends
Areenemies
and X and y is its parameters, which is integers in the range [0, N), identifying (different) people.
The last line contains ' 0 0 0 '.
All integers in the input file is separated by at least one space or line break. The only constraint
is n < 10000, the number of operations is unconstrained.
Output
For every "Arefriends" and "areenemies" Operation write ' 0 ' (meaning no) or ' 1 ' (meaning yes) to the output. Also for every "setfriends" or "setenemies" operation which contradicts with previous knowledge, output a '-1 ' to the OUTP Ut Note that such a operation should produce no other effect and execution should continue. A successful "setfriends" or "setenemies" gives no output. All integers in the output file must is separated by one line break.
Sample Input
10
1 0 1
1 1 2
2 0 5
3 0 2
3 8 9
4 1 5
4 1 2
4 8 9
1 8 9
1 5 2
3 5 2
0 0 0
Sample Output
1
0
1
0
0
-1
0
English:
There are n individuals who enter two different countries, and they negotiate, and now let you judge each other by the conversation between them as friends and foes.
There are 4 operations, Setfriends (x, y), setenemies (x, y), arefriends (x, y), areenemies (x, y), labeled with 1 to 4 digits
If it is set: operation, if it conflicts with the previous judgment, then output-1, otherwise not output. If the IS is operation: If you determine the correct output 1 otherwise output 0
#include <bits/stdc++.h> using namespace std;
const int maxn=10001;
int FATHER[MAXN],OFFSET[MAXN];
int Find (int x) {if (x!=father[x]) {int tmp=father[x];
Father[x]=find (Father[x]);
Offset[x]= (offset[x]+offset[tmp])%2;
cout<< "Find" <<x<< "<<tmp<<" "<<offset[x]<<endl;
} return father[x];
} int Union (int x,int y,int d) {int fx=find (x);
int Fy=find (y);
if (fx==fy) {//cout<< "union" <<offset[x]<< "" <<offset[y]<<endl;
if ((offset[x]-offset[y]+2)%2!=d) return-1;
else return 1;
} father[fy]=fx;
offset[fy]= (offset[x]-offset[y]+d+2)%2;
cout<< "union" <<offset[x]<< "" <<offset[y]<<endl;
return 0;
} void init (int n) {for (int i=0;i<=n;i++) father[i]=i;
memset (offset,0,sizeof (offset));
} int main () {Ios::sync_with_stdio (false); Int N
while (cin>>n) {int x,y,d;
Init (n);
while (cin>>d>>x>>y,x+y+d) {if (d<=2) {d--;
if (Union (x,y,d) ==-1) {cout<<-1<<endl;
}} else {d-=3;
Father[y]=find (y);
cout<< "..." <<endl;
Father[x]=find (x);
cout<< "offset" <<offset[x]<< "" <<offset[y]<<endl;
cout<< "Father" <<father[x]<< "" <<father[y]<<endl;
if (father[x]==father[y]&& (offset[x]-offset[y]+2)%2==d) cout<<1<<endl;
else cout<<0<<endl;
}}//break;
} return 0;
}
Ideas:
Very classic and check set plus vector offset, the first time to do this kind of problem is POJ on the food chain, I remember I just learned and check set when encountered this problem, because at that time the recursive understanding of the bad, this problem simply put me disgusting bad. I did not expect to be able to meet it again on the UVA.
Vector offset is the process of the path compression of the set and the transition between the child node and the parent node, and the maintenance of the relationship transformation enables the given node relationship to be classified by the relationship between the parent nodes.
Now set offset offset[] to record the current node's offset from the parent node (because each node in the set has only one parent node)
In this case, just set two relationships, friends and enemies.
When you set an offset of offset[x]=0, the relationship between X and the parent node is a friend, and Offset[x]=1 indicates that the relationship between the X and the parent node is an enemy.
Then, as shown in the original relationship, can be converted to the following relationship (two-side hostile so that the value between two nodes is 1, otherwise 0, arrow direction indicates the parent node direction)
After conversion
Enemy enemies become friends, so 1 and 3 are a bunch.
Then in the find () process, which is the process of finding the root node, the relationship between the current node and the parent node is judged by path compression.
The offset between the offset[x]= (Offset[x]+offset[father[x]])%2 x node and the new parent node equals the offset between the parent node and the parent node, and modulo 2 is designed for only two states, That is, friends and enemies, if not the modulo operation, you have to use if judgment, more trouble.
In the process of merging, that is, the process of setting up a relationship between two nodes.
The parent node of X, y of two nodes is first found fx,fy. If the FX and FY are equal, indicating that x and Y have been connected before and already have a relationship, then determine whether the relationship that is currently being set conflicts with the previous relationship. The way to judge collisions is to determine if X and Y have the same offset for their root nodes, and if X and Y both think the root node is an enemy or a friend, then X and y must be accomplices, otherwise they are enemies, using formulas
(offset[x]-offset[y]+2)%2!=d d is x and Y to set the relationship, only 0 and 12, 0 is a friend, 1 is the enemy. The formula result is true, indicating a conflict with the previous.
If the parent node of the two nodes x and y that you want to set is not the same, the relationship between x and Y is not established, that is, you do not know whether it is a friend or an enemy.
Then, the relationship between X and Y is established by the given relationship d.
First, the parent node fy of y is connected to FX above, representing X and Y, and all data connected to the X, y vector.
Then, calculate the offset value of the new connected node to the parent node (before FX as the parent of the FY, then calculate the offset of the FY and FX)
How to calculate the offset value. There is an offset value between X and FX, an offset between Y and FY, and an offset between x and Y (that is, to set the relationship value D between x and Y), and now requires the value between FX and FY. , using the knowledge of vectors.
To change the arrow point, just subtract the value of offset by the number of categories, 2 (Enemies and friends)
(if FY is equal to Y, then offset[y]=0)
Finally, the above calculation can be used to obtain a variety of results, the number of species can also be extended to 3
Challenge Program Design Competition There is another way, the book is detailed
Give a set of data and manually simulate it again
5
2 0 1
2 1 2
2 2 3
3 0 2
3 1 2
0 0 0