USACO Bronze 2018 Open - Family Tree
Authors: Danh Ta Chi Thanh, Ryan Chou, Chuyang Wang, Kevin Sheng, Amogha Pokkulandra
Video Solution
By Amogha Pokkulandra
Video Solution Code
Solution 1
By finding the closest common ancestor and the distances from the ancestor to the two cows, we can uniquely identify their relationship.
Implementation
Time Complexity:
Python
import syssys.stdin = open("family.in", "r")sys.stdout = open("family.out", "w")rel_num, cow_a, cow_b = input().split()relations = []for i in range(int(rel_num)):relations.append(input().split())
Java
import java.io.*;import java.util.*;public class FamilyTree {public static void main(String[] args) throws IOException {BufferedReader in = new BufferedReader(new FileReader("family.in"));PrintWriter out = new PrintWriter("family.out");StringTokenizer st = new StringTokenizer(in.readLine());int relNum = Integer.parseInt(st.nextToken());
C++
#include <fstream>#include <string>#include <vector>using std::string;using std::vector;using Relation = std::pair<string, string>;// finds the mother of given child among those pairs (returns null if no mother)string mother(const string &child, const vector<Relation> &relations) {
Solution 2
Similar to solution 1, but we find the common ancestor of the two cows more efficiently.
Implementation
Time Complexity:
Java
import java.io.*;import java.util.*;public class Family {public static void main(String[] args) throws IOException {BufferedReader read = new BufferedReader(new FileReader("family.in"));StringTokenizer initial = new StringTokenizer(read.readLine());int N = Integer.parseInt(initial.nextToken());String[] cows = new String[] {initial.nextToken(), initial.nextToken()};
C++
#include <bits/stdc++.h>using namespace std;int main() {freopen("family.in", "r", stdin);int N;vector<string> cows(2);cin >> N >> cows[0] >> cows[1];map<string, string> edge;
Python
with open("family.in") as read:cows = [None, None]N, cows[0], cows[1] = read.readline().split()N = int(N)edge = {}for _ in range(N):v, u = read.readline().split()edge[u] = v
Solution 3
Let's first create a map from each cow to its parent. Now let's handle this case by case.
and being siblings is equivalent to them having the same parent.
being a *-mother of is equivalent to equaling some ancestor of . We can iterate over the ancestors of by starting with our current cow being and then repeatedly setting the current cow to its parent.
being a *-aunt of is equivalent and some ancestor of being siblings. We can handle this by combining cases 1 and 2.
We can handle being a *-mother of and being a *-aunt of by swapping and and applying the same logic.
If and 's oldest ancestors are the same, then they are related.
Otherwise, if none of the cases above apply, then and are not related.
Implementation
Time Complexity:
C++
#include <bits/stdc++.h>using namespace std;int main() {ifstream fin("family.in");ofstream fout("family.out");int N;string c1, c2;fin >> N >> c1 >> c2;
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!