Submission

Status:
[PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP]

Score: 100

User: sleepntsheep

Problemset: Optimal Placement

Language: cpp

Time: 0.112 second

Submitted On: 2025-02-27 22:51:56

#include <stdio.h>
#include <stdlib.h>
#include <tuple>
#include <cassert>
#include <vector>

using namespace std;

int asgn[100000];

struct TwoSatSolver {
  int n_vars;
  int n_vertices;
  vector<vector<int>> adj, adj_t;
  vector<bool> used;
  vector<int> order, comp;
  vector<bool> assignment;

  TwoSatSolver(int _n_vars) : n_vars(_n_vars), n_vertices(2 * n_vars), adj(n_vertices), adj_t(n_vertices), used(n_vertices), order(), comp(n_vertices, -1), assignment(n_vars) {
    order.reserve(n_vertices);
  }
  void dfs1(int v) {
    used[v] = true;
    for (int u : adj[v]) {
      if (!used[u])
        dfs1(u);
    }
    order.push_back(v);
  }

  void dfs2(int v, int cl) {
    comp[v] = cl;
    for (int u : adj_t[v]) {
      if (comp[u] == -1)
        dfs2(u, cl);
    }
  }

  bool solve_2SAT() {
    order.clear();
    used.assign(n_vertices, false);
    for (int i = 0; i < n_vertices; ++i) {
      if (!used[i])
        dfs1(i);
    }

    comp.assign(n_vertices, -1);
    for (int i = 0, j = 0; i < n_vertices; ++i) {
      int v = order[n_vertices - i - 1];
      if (comp[v] == -1)
        dfs2(v, j++);
    }

    assignment.assign(n_vars, false);
    for (int i = 0; i < n_vertices; i += 2) {
      if (comp[i] == comp[i + 1])
        return false;
      assignment[i / 2] = comp[i] > comp[i + 1];
    }
    return true;
  }

  void add_disjunction(int a, bool na, int b, bool nb) {
    // na and nb signify whether a and b are to be negated 
    a = 2 * a ^ na;
    b = 2 * b ^ nb;
    int neg_a = a ^ 1;
    int neg_b = b ^ 1;
    adj[neg_a].push_back(b);
    adj[neg_b].push_back(a);
    adj_t[b].push_back(neg_a);
    adj_t[a].push_back(neg_b);
  }

  static void example_usage() {
    TwoSatSolver solver(3); // a, b, c
    solver.add_disjunction(0, false, 1, true);  //     a  v  not b
    solver.add_disjunction(0, true, 1, true);   // not a  v  not b
    solver.add_disjunction(1, false, 2, false); //     b  v      c
    solver.add_disjunction(0, false, 0, false); //     a  v      a
    assert(solver.solve_2SAT() == true);
  }
};

int main()
{
  int n, m;

  scanf("%d%d", &n, &m);

  vector<tuple<int, int, int, int>> flags;

  for (int i = 0; i < m; ++i) {
    int x, y, w, z;
    scanf("%d%d%d%d", &x, &y, &w, &z);
    flags.emplace_back(x, y, w, z);
  }

  auto canPlace = [&](int d) -> bool {
    TwoSatSolver solver(m + m);
    for (int i = 0; i < m; ++i)
    {
      solver.add_disjunction(i, false, i + m, false);
      solver.add_disjunction(i, true, i + m, true);
    }

    auto dis = [&](int x, int y, int w, int z)
    {
      return abs(x - w) + abs(y - z);
    };

    for (int i = 0; i < m; ++i)
    {
      auto [xi, yi, wi, zi] = flags[i];
      for (int j = 0; j < m; ++j)
      {
        if (i == j)
          continue;
        auto [xj, yj, wj, zj] = flags[j];

        if (dis(xi, yi, xj, yj) < d)
        {
          solver.add_disjunction(i, true, j, true);
        }

        if (dis(xi, yi, wj, zj) < d)
        {
          solver.add_disjunction(i, true, j + m, true);
          //solver.add_disjunction(i, true, j, false);
        }

        if (dis(wi, zi, xj, yj) < d)
        {
          solver.add_disjunction(i + m, true, j, true);
          //solver.add_disjunction(i, false, j, true);
        }

        if (dis(wi, zi, wj, zj) < d)
        {
          solver.add_disjunction(i + m, true, j + m, true);
          //solver.add_disjunction(i, false, j, false);
        }
      }
    }


    bool ret;
    ret = solver.solve_2SAT();
    //printf(" %d %d\n",d,(int)ret);

    if (ret)
    {
      for (int i = 0; i < m; ++i)
        asgn[i] = solver.assignment[i] ? 'A' : 'B';
    }
    return ret;
  };

  int low = 0, high = n + n, ans = 0;

  while (low <= high) {
    int mid = (low + high) / 2;

    if (canPlace(mid)) {
      ans = mid;
      low = mid + 1;
    } else {
      high = mid - 1;
    }
  }

  printf("%d\n", ans);

  canPlace(ans);

  for (int i = 0; i < m; ++i)
    putchar(asgn[i]);

  return 0;
}