Explanation
Since the relation of friends is transitive, we can keep sets in which all the people in a set are friends. For each of these sets of friends, there will also be a set of enemies made up of the union of all the enemies of each person in the set of friends. Every person in this set of enemies will be an enemy of every person in the set of friends. To see why this is true, consider a person in the set of friends . Their enemy is in the set of enemies . Since an enemy of a friend is also an enemy, will be the enemy of all of 's friends, which are the other people . Furthermore, each person in is friends with all other people in , since they share a common enemy .
To represent this, sets in the code will be sets of friends, while each set in sets will be be the enemies of set .
For each query, we let the two people be and and the root of 's friends, 's friends, 's enemies and 's enemies be , , and , respectively.
areEnemies
If any of 's friends are friends with any of 's enemies, then will be friends with one of 's enemies. Thus, and will be enemies. To check if this is the case, we check if is the same as (which means that 's friends are 's enemies), or if is the same as (which means that 's friends are 's enemies).
areFriends
If and are in the same set, then they are friends.
setEnemies
When setting two people as enemies, we need to check if they are friends. We can use the function to do this. If they are not friends, we join 's set with 's set and join 's set with 's set, since the friend of an enemy is also an enemy.
setFriends
If we want to set two people as friends, we first need to check if they are enemies, using the function. If they are not enemies, we can join 's and 's sets. The enemies of two sets of friends will also become friends, so we also join 's and 's sets.
Implementation
Time Complexity: , where is the number of operations
C++
#include <algorithm>#include <iostream>using namespace std;int size[20000], parent[20000];void init(int n) {for (int i = 0; i < 2 * n; i++) {parent[i] = i;size[i] = 1;}
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!