제출 #1019472

#제출 시각아이디문제언어결과실행 시간메모리
1019472spacewalker친구 (IOI14_friend)C++17
27 / 100
1038 ms9776 KiB
#include <bits/stdc++.h>

#include "friend.h"

using namespace std;

inline int connects_self(int p) {
  return p == 0 || p == 2;
}

inline int connects_neighbors(int p) {
  return p == 1 || p == 2;
}

// Find out best sample
int findSample(int n,int confidence[],int host[],int protocol[]){
  vector<vector<int>> children(n, vector<int>());
  for (int i = 1; i < n; ++i) children[host[i]].push_back(i);

  // first y/n: does there exist an indirect neighbor we picked
  // (path of neighbor-connects that goes up, then a direct connect,
  //  then the path goes back down through neighbor-connects)
  // second y/n: did we pick this node?
  // note that yy cannot happen; since the indirect neighbor and this node
  // are adjacent
  vector<int> best_nn(n), best_yn(n), best_ny(n);
  for (int i = n - 1; i >= 0; --i) {
    // We do some DP to account for the fact that a child might become
    // an indirect neighbor of another child's sibling.
    // maintain DP on suffixes of the list of children:
    // - max if we pick no neighbor-connected child
    //  - MUST pick yn if current child is neighbor-connected
    // - max if we picked some neighbor-connected child
    //  - MUST pick yn if current child is self-connected but not neighbor-contained
    //    then transition to next on some table
    //  - otherwise, can pick any (?)
    //
    // Aside from this, the 3 cases are:
    // best_nn: this DP runs as normal
    // best_yn: MUST pick yn if child connects_neighbors 
    // best_ny: MUST pick yn if child connects_self
    //
    // (these conditions being active are denoted by free_neighbor and free_self = false,
    // respectively)
    for (auto recurrence : {0, 1, 2}) { // nn, yn, ny
      vector<int> &table = (recurrence == 0 ? best_nn :
          (recurrence == 1 ? best_yn : best_ny));
      vector<int> no_neigh_connect(children.size() + 1), with_neigh_connect(children.size() + 1);
      bool free_neighbor = recurrence != 1;
      bool free_self = recurrence != 2;
      for (int k = (int)children[i].size() - 1; k >= 0; --k) {
        int v = children[i][k];
        auto must_yn = [&] (int v, bool free_neighbor, bool free_self) {
          bool must_yn = (!free_neighbor && connects_neighbors(protocol[v])) 
            || (!free_self && connects_self(protocol[v]));
          // cerr << "must yn " << must_yn << endl;
          return must_yn;
        };
        // update no_neigh_connect[k]
        if (must_yn(v, false, free_self)) {
          no_neigh_connect[k] = best_yn[v] + no_neigh_connect[k+1];
        } else {
          no_neigh_connect[k] = best_nn[v] + no_neigh_connect[k+1];
          if (!connects_neighbors(protocol[v])) {
            no_neigh_connect[k] = max(no_neigh_connect[k], best_ny[v] + no_neigh_connect[k+1]);
          }
        }
        // update with_neigh_connect[k]
        if (must_yn(v, free_neighbor, free_self) || (connects_self(protocol[v]) && !connects_neighbors(protocol[v]))) {
          with_neigh_connect[k] = best_yn[v] + with_neigh_connect[k+1];
        } else {
          with_neigh_connect[k] = best_nn[v] + with_neigh_connect[k+1];
          with_neigh_connect[k] = max(with_neigh_connect[k], best_ny[v] + with_neigh_connect[k+1]);
          if (connects_neighbors(protocol[v])) {
            with_neigh_connect[k] = max(with_neigh_connect[k], best_ny[v] + no_neigh_connect[k+1]);
          }
        }
        // cerr << "HN" << no_neigh_connect[k] << " " << with_neigh_connect[k] << endl;
      }
      if (children[i].size() > 0) {
        table[i] = max(no_neigh_connect[0], with_neigh_connect[0]);
        // cerr << "recc " << i << " " << recurrence << " " << table[i] << endl;
      }
    }
    best_ny[i] += confidence[i];
    // cerr << i << " values " << best_nn[i] << " " << best_yn[i] << " " << best_ny[i] << endl;
  }
  
  return max(best_nn[0], best_ny[0]);
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...