private void solve(Team t) {
    if (eliminators.containsKey(t.name)) {
      return;
    } // result is cached, so don't recalculate it

    // Trivial elimination
    if (!t.equals(teams[leader]) && isTriviallyEliminated(t)) {
      eliminators.put(
          t.name,
          new SET<String>() {
            {
              add(teams[leader].name);
            }
          }); // I bet checkstyle HATES this. //TODO: I bet this is a bug where sliminators are
              // overwritten
      return;
    }

    // Maxflowy realzo elimination
    FordFulkerson ffFlow = graphTheTeam(t);
    if (isNumericallyEliminated(t, ffFlow.value())) {
      for (int i = 0; i < numberOfTeams(); i++) {
        if (ffFlow.inCut(i)) {
          SET<String> winners = new SET<String>();
          if (eliminators.containsKey(t.name)) {
            winners = eliminators.get(t.name);
          }
          winners.add(teams[i].name);
          eliminators.put(t.name, winners);
        }
      }
    }
  }
Пример #2
0
  /** @return is given team eliminated? */
  public boolean isEliminated(String team) {
    checkArgument(team);
    int teamIndex = team2Index.get(team);
    int maxPossibleWinCount = remainingCounts[teamIndex] + winCounts[teamIndex];
    if (maxPossibleWinCount < maxWinCountCurrent) {
      return true;
    }

    int nodeCount =
        2 // s, t
            + teamCount * (teamCount - 1) / 2 // game vertices
            + teamCount; // team vertices
    // 0..N-1 for team vertices
    // N..N*(N+1)/2 for game vertices
    // last 2 node for s and t
    FlowNetwork network = new FlowNetwork(nodeCount);
    int s = nodeCount - 2;
    int t = nodeCount - 1;
    double sCapacity = 0;
    // edge from team vertices to t
    for (int i = 0; i < teamCount; i++) {
      if (i != teamIndex) {
        double weight = maxPossibleWinCount - winCounts[i];
        FlowEdge edge = new FlowEdge(i, t, weight);
        network.addEdge(edge);
      }
    }
    int gameNodeIndex = teamCount - 1;
    for (int i = 0; i < teamCount; i++) {
      for (int j = i + 1; j < teamCount; j++) {
        gameNodeIndex++;
        if (i == teamIndex || j == teamIndex) {
          continue;
        }
        // edge from s to game vertices
        double weight = remainGames[i][j];
        FlowEdge edge = new FlowEdge(s, gameNodeIndex, weight);
        network.addEdge(edge);
        sCapacity += weight;

        // edges from game vertices to team vertices
        edge = new FlowEdge(gameNodeIndex, i, Double.POSITIVE_INFINITY);
        network.addEdge(edge);
        edge = new FlowEdge(gameNodeIndex, j, Double.POSITIVE_INFINITY);
        network.addEdge(edge);
      }
    }

    FordFulkerson alg = new FordFulkerson(network, s, t);
    if (Math.abs(alg.value() - sCapacity) < 1E-6) {
      return false;
    }
    return true;
  }
  public BaseballElimination(String filename) {
    In in = new In(filename);
    V = in.readInt();
    teamID = new ST<String, Integer>();
    teamName = new ST<Integer, String>();
    teamInfo = new int[V][V + 3];
    subset = (Bag<Integer>[]) new Bag[V];
    elimin = new Boolean[V];
    for (int i = 0; i < V; i++) {
      subset[i] = new Bag<Integer>();
    }
    for (int i = 0; i < V; i++) {
      String name = in.readString();
      teamID.put(name, i);
      teamName.put(i, name);
      for (int j = 0; j < V + 3; j++) {
        teamInfo[i][j] = in.readInt();
      }
    }

    int offset = 1 + V * (V - 1) / 2;
    for (int x = 0; x < V; x++) {
      if (trivalElimination(x)) {
        // StdOut.println("team " + teamName.get(x) + "is trivally eliminated");
        elimin[x] = true;
        continue;
      }
      FlowNetwork G = new FlowNetwork(offset + V + 1);
      int s = 0;
      int t = offset + V;
      int point = 1;
      int remainGameNumber = 0;
      for (int i = 0; i < V; i++) {
        for (int j = i + 1; j < V; j++) {
          if (i == x || j == x) {
            point++;
            continue;
          }
          if (teamInfo[i][j + 3] > 0) {
            FlowEdge edge = new FlowEdge(s, point, teamInfo[i][j + 3]);
            remainGameNumber += teamInfo[i][j + 3];
            G.addEdge(edge);
            FlowEdge edge1 = new FlowEdge(point, offset + i, Double.POSITIVE_INFINITY);
            FlowEdge edge2 = new FlowEdge(point, offset + j, Double.POSITIVE_INFINITY);
            G.addEdge(edge1);
            G.addEdge(edge2);
          }
          point++;
        }
      }
      for (int i = 0; i < V; i++) {
        if (i == x) continue;
        int capacity = teamInfo[x][0] + teamInfo[x][2] - teamInfo[i][0];
        FlowEdge edge = new FlowEdge(offset + i, t, capacity);
        G.addEdge(edge);
      }
      FordFulkerson maxflow = new FordFulkerson(G, s, t);
      if (maxflow.value() == remainGameNumber) {
        elimin[x] = false;
      } else {
        elimin[x] = true;
        if (debug == true) {
          StdOut.println("FlowNetWork" + G.toString());
        }
        for (int i = 0; i < V; i++) {
          if (i == x) continue;
          if (maxflow.inCut(offset + i)) {
            subset[x].add(i);
          }
        }
      }
    }
  }