Minimize Maximum Stadium Size - Google Top Interview Questions


Problem Statement :


You are given an integer n and a two-dimensional list of integers views. 

There are n teams in a tournament and you want to build two stadiums to host the games.

 Each element in views contains [a, b, people] meaning that when team a and team b compete, there are people number of people that will view that game. 

The viewership numbers among every pair of teams will be in views.

You must permanently assign each team to a stadium. Every team in a stadium plays every other team in that stadium, and only within that stadium.

Return the smallest possible maximum capacity of the two stadiums, where the capacity of a stadium is the number of seats required to fit the largest audience of a game in that stadium.

Constraints

2 ≤ n ≤ 500

1 ≤ m ≤ 200,000 where m is the length of views

Example 1

Input

n = 3

views = [

    [0, 1, 100],

    [0, 2, 900],

    [1, 2, 500]

]

Output

100

Explanation

We can put teams 0 and 1 in one stadium and team 2 in the other stadium. This means team 2 doesn't 
have to compete with any other team. Then, for the first stadium we need capacity of 100 to host the 
game between teams 0 and 1.



Example 2

Input

n = 2

views = [

    [0, 1, 100]

]

Output

0

Explanation

If we put each team in separate stadiums, then they don't have to compete.



Example 3

Input

n = 4

views = [

    [0, 1, 4],

    [0, 2, 1],

    [0, 3, 5],

    [1, 2, 4],

    [1, 3, 3],

    [2, 3, 4]

]

Output

3

Explanation

We can place teams 0 and 2 in one stadium, and 1 and 3 in the other stadium. In the first stadium, we 

need capacity of 1 and in the second stadium we need capacity of 3.



Solution :



title-img




                        Solution in C++ :

int n, graph[501][501], which_stadium[501];
bool possible(int team, int stadium, const int& max_people) {
    which_stadium[team] = stadium;
    for (int i = 0; i < n; i++) {
        if (which_stadium[i] != -1 && graph[team][i] > max_people &&
            which_stadium[i] != (stadium ^ 1))
            return false;
        else if (which_stadium[i] == -1 && graph[team][i] > max_people)
            if (!possible(i, stadium ^ 1, max_people)) return false;
    }
    return true;
}

int solve(int n, vector<vector<int>>& views) {
    ::n = n;
    int left = 0, right = 0;
    for (auto& v : views) right = max(right, graph[v[0]][v[1]] = graph[v[1]][v[0]] = v[2]);

    auto can = [&](int mid) {
        fill(which_stadium, which_stadium + n, -1);
        for (int i = 0; i < n; i++)
            if (which_stadium[i] == -1 && !possible(i, 0, mid)) return false;
        return true;
    };

    while (left < right) {
        int mid = left + (right - left) / 2;
        if (can(mid))
            right = mid;
        else
            left = mid + 1;
    }
    return right;
}
                    


                        Solution in Java :

import java.util.*;

class Solution {
    static ArrayList<Integer>[] graph;
    public int solve(int N, int[][] views) {
        sort(views);
        graph = new ArrayList[N];
        for (int i = 0; i < N; i++) {
            graph[i] = new ArrayList<Integer>();
        }

        for (int i = views.length - 1; i >= 0; i--) {
            // update the graph
            graph[views[i][0]].add(views[i][1]);
            graph[views[i][1]].add(views[i][0]);

            // if there's an odd cycle, its impossible to assign stadiums.
            if (!bipartite()) {
                return views[i][2];
            }
        }
        return 0;
    }

    public static boolean bipartite() {
        int N = graph.length;
        // assign 1-2 colors
        int[] color = new int[N];
        for (int i = 0; i < N; i++) {
            if (color[i] == 0) {
                color[i] = 1;
                ArrayDeque<Integer> bfs = new ArrayDeque<Integer>();
                bfs.add(i);
                while (!bfs.isEmpty()) {
                    int n = bfs.pollFirst();
                    for (int next : graph[n]) {
                        if (color[next] == 0) {
                            color[next] = 3 - color[n];
                            bfs.add(next);
                        } else if (color[next] == color[n]) {
                            return false;
                        }
                    }
                }
            }
        }
        return true;
    }

    public static void sort(int[][] arr) {
        Arrays.sort(arr, new Comparator<int[]>() {
            @Override
            public int compare(int[] a, int[] b) {
                return a[2] - b[2];
                // Ascending order.
            }
        });
    }
}
                    


                        Solution in Python : 
                            
class Solution:
    def solve(self, n, views):
        if n <= 2:
            return 0

        dist = [[-1] * n for _ in range(n)]
        e = collections.defaultdict(list)
        for x, y, v in views:
            dist[x][y] = v
            dist[y][x] = v

        def two_colorable(target):
            color = [-1] * n
            found = False

            def go(x, c, target):
                for y in range(n):
                    v = dist[x][y]
                    if v > target:
                        if color[x] == color[y]:
                            nonlocal found
                            found = True
                            return
                        elif color[y] == -1:
                            color[y] = 1 - c
                            go(y, 1 - c, target)

            for x in range(n):
                if color[x] == -1:
                    color[x] = 1
                    go(x, 1, target)
                    if found:
                        return False
            return True

        left = 0
        right = 10 ** 10
        while left < right:
            mid = (left + right) // 2
            if two_colorable(mid):
                right = mid
            else:
                left = mid + 1
        return left
                    


View More Similar Problems

Get Node Value

This challenge is part of a tutorial track by MyCodeSchool Given a pointer to the head of a linked list and a specific position, determine the data value at that position. Count backwards from the tail node. The tail is at postion 0, its parent is at 1 and so on. Example head refers to 3 -> 2 -> 1 -> 0 -> NULL positionFromTail = 2 Each of the data values matches its distance from the t

View Solution →

Delete duplicate-value nodes from a sorted linked list

This challenge is part of a tutorial track by MyCodeSchool You are given the pointer to the head node of a sorted linked list, where the data in the nodes is in ascending order. Delete nodes and return a sorted list with each distinct value in the original list. The given head pointer may be null indicating that the list is empty. Example head refers to the first node in the list 1 -> 2 -

View Solution →

Cycle Detection

A linked list is said to contain a cycle if any node is visited more than once while traversing the list. Given a pointer to the head of a linked list, determine if it contains a cycle. If it does, return 1. Otherwise, return 0. Example head refers 1 -> 2 -> 3 -> NUL The numbers shown are the node numbers, not their data values. There is no cycle in this list so return 0. head refer

View Solution →

Find Merge Point of Two Lists

This challenge is part of a tutorial track by MyCodeSchool Given pointers to the head nodes of 2 linked lists that merge together at some point, find the node where the two lists merge. The merge point is where both lists point to the same node, i.e. they reference the same memory location. It is guaranteed that the two head nodes will be different, and neither will be NULL. If the lists share

View Solution →

Inserting a Node Into a Sorted Doubly Linked List

Given a reference to the head of a doubly-linked list and an integer ,data , create a new DoublyLinkedListNode object having data value data and insert it at the proper location to maintain the sort. Example head refers to the list 1 <-> 2 <-> 4 - > NULL. data = 3 Return a reference to the new list: 1 <-> 2 <-> 4 - > NULL , Function Description Complete the sortedInsert function

View Solution →

Reverse a doubly linked list

This challenge is part of a tutorial track by MyCodeSchool Given the pointer to the head node of a doubly linked list, reverse the order of the nodes in place. That is, change the next and prev pointers of the nodes so that the direction of the list is reversed. Return a reference to the head node of the reversed list. Note: The head node might be NULL to indicate that the list is empty.

View Solution →