2-SAT经典题样例不过求调
查看原帖
2-SAT经典题样例不过求调
355510
Lightwhite楼主2022/6/27 21:33
#include <iostream>
#include <algorithm>
#include <cstring>
#include <stack>

using namespace std;
const int kN = 1e6 + 5, kM = 2e3 + 5;

stack <int> s;
int n, m, t, p, tot, cnt, rec, c[kN], x[kN], y[kN], h[kN], ex[kN], ey[kN], b[kN], vis[kN], d[kN], ins[kN], l[kN], f[kM][kM];
struct Edge {
  int v, nxt;
} ed[kN << 1];
void add (int u, int v) {
  ed[++cnt] = {v, h[u]}, h[u] = cnt;
}
void DFS (int x) {
  d[x] = l[x] = ++p, s.push (x), ins[x] = 1;
  for (int i = h[x]; i; i = ed[i].nxt) {
    int v = ed[i].v;
    (!d[v]) ? (DFS (v), l[x] = min (l[x], l[v])) : (ins[v] ? l[x] = min (l[x], d[v]) : 0);
  }
  if (l[x] == d[x]) {
    rec++;
    do {
      b[x] = rec, x = s.top (), s.pop (), ins[x] = 0;
    } while (l[x] != d[x]);
  }
}
bool judge () {
  for (int i = 1; i <= m << 1; i++) {
    (!d[i]) ? DFS (i) : void ();
  }
  for (int i = 1; i <= m; i++) {
    // cerr << b[i] << ' ' << b[i + n] << '\n';
    if (b[i] == b[i + n]) {
      return false;
    }
  }
  return true;
}
int main () {
  ios :: sync_with_stdio (false);
  cin.tie (0), cout.tie (0);

  cin >> t;
  while (t--) {
    cnt = tot = rec = p = 0;
    memset (h, 0, sizeof (h)), memset (d, 0, sizeof (d)), memset (l, 0, sizeof (l)), memset (b, 0, sizeof (b)), memset (f, 0, sizeof (f));
    cin >> n >> m;
    for (int i = 1; i <= m; i++) {
      cin >> x[i] >> y[i], (x[i] > y[i] ? swap (x[i], y[i]) : void ());
    }
    for (int i = 1; i <= n; i++) {
      cin >> c[i], vis[c[i]] = i;
      if (i > 1) {
        int a = c[i - 1], b = c[i];
        a < b ? (f[a][b] = 1) : (f[b][a] = 1);
      }
    }
    if (m > 3 * n - 6) {
      cout << "NO" << '\n';
      continue;
    }
    int a = c[n], b = c[1];
    a < b ? (f[a][b] = 1) : (f[b][a] = 1);
    for (int i = 1; i <= m; i++) {
      (!f[x[i]][y[i]]) ? (ex[++tot] = x[i], ey[tot] = y[i]) : 0;
    }
    m = tot;
    for (int i = 1, u, v, w, z; i < m; i++) {
      for (int j = i + 1; j <= m; j++) {
        u = vis[ex[i]], v = vis[ey[i]], w = vis[ex[j]], z = vis[ey[j]];
        (u > v ? swap (u, v) : void ()), (w > z ? swap (w, z) : void ());
        if ((u < w && v > w && v < z) || (u > w && u < z && v > z)) {
          add (i, j + m), add (i + m, j), add (j, i + m), add (j + m, i);
        }
      }
    }
    cout << (judge () ? "YES" : "NO") << '\n';
  }
  return 0;
}

plz

2022/6/27 21:33
加载中...