USACO Silver 2019 December - Milk Visits

Authors: Qi Wang, Tanish Tyagi, Kevin Sheng


Official Analysis (C++)

Time Complexity: O(N+M)\mathcal{O}(N + M)

We perform a search on the tree, identifying connected components of cows that all have the same breed.

In the sample test case, there are 33 connected components:

  • Component 00: Farms 11, 22, and 44
  • Component 11: Farm 33
  • Component 22: Farm 55

Next, we assign the farms in each component a number corresponding to the component they are in. For example, in the sample test case, farm 11 would get the number 00, 33 would get the number 11, and so on and so forth.

When checking if a visiting farmer going from farm AA to BB will be happy, there's two possible cases:

  1. Farms AA and BB are part of the same component. This means the path between AA and BB only contains cows of the same breed. If the farmer prefers milk from this breed, then we should output 11 and 00 otherwise.
  2. Farms AA and BB are part of different components. This means that the farmer will always be satisfied because the path between AA and BB contains both breeds of cows, and so we should always output 11.

Here's a walkthrough for the sample test case queries:

  1. Farms 11 and 44 are in the same component, and since Farmer 11's preferred cow is Holstein, they will be satisfied. (11)
  2. Farms 11 and 44 are in the same component, but since Farmer 22's preferred cow is Guernsey, they will be unsatisfied. (00)
  3. Farms 11 and 33 are in different components, so Farmer 33 will be satisfied. (11)
  4. Same logic as query 33. (11)
  5. Farm 55 is Guernsey, and Farmer 55's preferred cow is Holstein, they will be unsatisfied. (00)

C++

#include <algorithm>
#include <cassert>
#include <fstream>
#include <iostream>
#include <vector>
using std::cout;
using std::endl;
using std::vector;

Java

import java.io.*;
import java.util.*;
public class MilkVisits {
public static void main(String[] args) throws IOException {
BufferedReader read = new BufferedReader(new FileReader("milkvisits.in"));
StringTokenizer initial = new StringTokenizer(read.readLine());
int farmNum = Integer.parseInt(initial.nextToken());
int queryNum = Integer.parseInt(initial.nextToken());

Python

with open("milkvisits.in") as read:
farm_num, query_num = [int(i) for i in read.readline().split()]
farms = read.readline()
neighbors = [[] for _ in range(farm_num)]
for f in range(farm_num - 1):
f1, f2 = [int(i) - 1 for i in read.readline().split()]
neighbors[f1].append(f2)
neighbors[f2].append(f1)
queries = []

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!