제출 #1329908

#제출 시각아이디문제언어결과실행 시간메모리
1329908SmuggingSpun장난감 기차 (IOI17_train)C++20
큐에 대기중
0 ms0 KiB
#include "train.h"
#include<bits/stdc++.h>
using namespace std;
template<class T>void minimize(T& a, T b){
  if(a > b){
    a = b;
  }
}
const int lim = 5005;
vector<int>a, r, u, v, g[lim];
int n, m;
namespace sub1{
  bool check_subtask(){
    for(int i = 0; i < m; i++){
      if(v[i] != u[i] && v[i] != u[i] + 1){
        return false;
      }
    }
    return true;
  }
  vector<int>solve(){
    vector<int>dp(n + 1);
    dp[n] = 0;
    vector<vector<bool>>have(n, vector<bool>(2, false));
    for(int i = 0; i < m; i++){
      have[u[i]][v[i] - u[i]] = true;
    }
    for(int i = n - 1; i > -1; i--){
      if(r[i]){
        if(a[i]){
          dp[i] = have[i][0] ? 1 : dp[i + 1];
        }
        else{
          dp[i] = have[i][1] ? dp[i + 1] : 1;
        }
      }
      else if(a[i]){
        dp[i] = have[i][1] ? dp[i + 1] : 0;
      }
      else{
        dp[i] = have[i][0] ? 0 : dp[i + 1];
      }
    }
    dp.pop_back();
    return dp;
  }
}
namespace sub3{
  bitset<lim>out, have_r, bs[lim];
  int tdfs = 0, cnt_color = 0, num[lim], low[lim], color[lim];
  vector<int>stk;
  void dfs(int s){
    low[s] = num[s] = ++tdfs;
    stk.push_back(s);
    for(int& d : g[s]){
      if(!out[d]){
        if(num[d] == 0){
          dfs(d);
          minimize(low[s], low[d]);
        }
        else{
          minimize(low[s], num[d]);
        }
      }
    }
    if(low[s] == num[s]){
      bs[cnt_color].reset();
      bs[cnt_color][cnt_color] = true;
      int siz = 0;
      while(true){
        int x = stk.back();
        stk.pop_back();
        siz++;
        color[x] = cnt_color;
        out[x] = true;
        if(r[x]){
          have_r[cnt_color] = true;
        }
        for(int& y : g[x]){
          if(color[y] != -1){
            bs[color[x]] |= bs[color[y]];
          }
        }
        if(x == s){
          break;
        }
      }
      if(siz < 2 && find(g[s].begin(), g[s].end(), s) == g[s].end()){
        have_r[cnt_color] = false;
      }
      cnt_color++;
    }
  }
  vector<int>solve(){
    for(int i = 0; i < m; i++){
      g[u[i]].push_back(v[i]);
    }
    out.reset();
    have_r.reset();
    memset(num, 0, sizeof(num));
    memset(color, -1, sizeof(color));
    for(int i = 0; i < n; i++){
      if(num[i] == 0){
        dfs(i);
      }
    }
    vector<int>ans(n, 0);
    for(int i = 0; i < n; i++){
      for(int j = 0; j < cnt_color; j++){
        if(have_r[j] && bs[color[i]][j]){
          ans[i] = 1;
          break;
        }
      }
    }
    return ans;
  }
}
namespace sub4{
  bitset<lim>vis, cyc, have_cyc, bs[lim];
  bool dfs_1(const int root, int s){
    vis[s] = true;
    for(int& d : g[s]){
      if(!r[d] && (d == root || (!vis[d] && dfs_1(root, d)))){
        return true;
      }
    }
    return false;
  }
  int tdfs = 0, cnt_color = 0, num[lim], low[lim], color[lim];
  vector<int>stk;
  void dfs_2(int s){
    low[s] = num[s] = ++tdfs;
    stk.push_back(s);
    for(int& d : g[s]){
      if(!vis[d]){
        if(num[d] == 0){
          dfs_2(d);
          minimize(low[s], low[d]);
        }
        else{
          minimize(low[s], num[d]);
        }
      }
    }
    if(low[s] == num[s]){
      bs[cnt_color].reset();
      bs[cnt_color][cnt_color] = true;
      while(true){
        int x = stk.back();
        stk.pop_back();
        color[x] = cnt_color;
        vis[x] = true;
        if(cyc[x]){
          have_cyc[cnt_color] = true;
        }
        for(int& y : g[x]){
          if(color[y] != -1){
            bs[color[x]] |= bs[color[y]];
          }
        }
        if(x == s){
          break;
        }
      }
      cnt_color++;
    }
  }
  vector<int>solve(){
    for(int i = 0; i < m; i++){
      g[u[i]].push_back(v[i]);
    }
    cyc.reset();
    for(int i = 0; i < n; i++){
      if(!r[i]){
        vis.reset();
        cyc[i] = dfs_1(i, i);
      }
    }
    memset(num, 0, sizeof(num));
    memset(color, -1, sizeof(color));
    vis.reset();
    for(int i = 0; i < n; i++){
      if(num[i] == 0){
        dfs_2(i);
      }
    }
    vector<int>ans(n, 1);
    for(int i = 0; i < n; i++){
      for(int j = 0; j < cnt_color; j++){
        if(have_cyc[j] && bs[color[i]][j]){
          ans[i] = 0;
          break;
        }
      }
    }
    return ans;
  }
}
namespace sub256{
  vector<int>solve(){
    vector<int>out_deg(n, 0), ans(n);
    for(int i = 0; i < m; i++){
      g[v[i]].push_back(u[i]);
      out_deg[u[i]]++;
    }
    while(true){
      queue<int>q;
      vector<int>deg(n);
      for(int i = 0; i < n; ans[i++] = 0){
        deg[i] = a[i] ? 1 : out_deg[i];
        if(r[i] == 1){
          q.push(i);
        }
      }
      while(!q.empty()){
        int s = q.front();
        q.pop();
        for(int& d : g[s]){
          if(--deg[d] == 0){
            ans[d] = 1;
            if(r[d] == 0){
              q.push(d);
            }
          }
        }
      }
      bool flag = true;
      for(int i = 0; i < n; i++){
        if(r[i] == 1 && ans[i] == 0){
          r[i] = 0;
          flag = false;
        }
      }
      if(flag){
        break;
      }
    }
    return ans;
  }
}
vector<int>who_wins(vector<int>_a, vector<int>_r, vector<int>_u, vector<int>_v){
  swap(a, _a);
  swap(r, _r);
  swap(u, _u);
  swap(v, _v);
  n = a.size();
  m = u.size();
  if(sub1::check_subtask()){
    return sub1::solve();
  }
  if(find(a.begin(), a.end(), 0) == a.end()){
    return sub3::solve();
  }
  if(find(a.begin(), a.end(), 1) == a.end()){
    return sub4::solve();
  }
  return sub256::solve();
}