Advertisement
qwerty787788

TwoSat

Oct 28th, 2018
197
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.05 KB | None | 0 0
  1. class TwoSat {
  2.         int[][] g;
  3.         int[][] gRev;
  4.         List<Integer> from, to;
  5.  
  6.         int n;
  7.  
  8.         TwoSat(int n) {
  9.             this.n = n * 2;
  10.             from = new ArrayList<>();
  11.             to = new ArrayList<>();
  12.         }
  13.  
  14.         void add(int x, boolean xOk, int y, boolean yOk) {
  15.             x = x * 2 + (xOk ? 1 : 0);
  16.             y = y * 2 + (yOk ? 1 : 0);
  17.             from.add(x);
  18.             to.add(y);
  19.         }
  20.  
  21.         void buildGraph() {
  22.             int[] gSz = new int[n];
  23.             int[] gRevSz = new int[n];
  24.             for (int i = 0; i < from.size(); i++) {
  25.                 int v = from.get(i), u = to.get(i);
  26.                 gSz[v]++;
  27.                 gRevSz[v ^ 1]++;
  28.                 gRevSz[u]++;
  29.                 gSz[u ^ 1]++;
  30.             }
  31.             g = new int[n][];
  32.             gRev = new int[n][];
  33.             for (int i = 0; i < n; i++) {
  34.                 g[i] = new int[gSz[i]];
  35.                 gRev[i] = new int[gRevSz[i]];
  36.             }
  37.             for (int i = 0; i < from.size(); i++) {
  38.                 int v = from.get(i), u = to.get(i);
  39.                 gSz[v]--;
  40.                 g[v][gSz[v]] = u;
  41.                 gRevSz[v ^ 1]--;
  42.                 gRev[v ^ 1][gRevSz[v ^ 1]] = u ^ 1;
  43.                 gRevSz[u]--;
  44.                 gRev[u][gRevSz[u]] = v;
  45.                 gSz[u ^ 1]--;
  46.                 g[u ^ 1][gSz[u ^ 1]] = v ^ 1;
  47.             }
  48.         }
  49.  
  50.         boolean[] used;
  51.         int[] comp;
  52.         int[] order;
  53.         int oSz;
  54.  
  55.         int[] q;
  56.         int[] it;
  57.  
  58.         void dfs1_nonRec(int v) {
  59.             used[v] = true;
  60.             int qSz = 1;
  61.             q[qSz - 1] = v;
  62.             it[0] = 0;
  63.             while (qSz > 0) {
  64.                 int vertex = q[qSz - 1];
  65.                 if (it[qSz - 1] == g[vertex].length) {
  66.                     it[qSz - 1] = 0;
  67.                     qSz--;
  68.                     order[oSz++] = vertex;
  69.                 } else {
  70.                     int to = g[vertex][it[qSz - 1]++];
  71.                     if (!used[to]) {
  72.                         used[to] = true;
  73.                         q[qSz++] = to;
  74.                     }
  75.                 }
  76.             }
  77.         }
  78.  
  79.         void dfs1(int v) {
  80.             used[v] = true;
  81.             for (int i = 0; i < g[v].length; i++) {
  82.                 int to = g[v][i];
  83.                 if (!used[to]) {
  84.                     dfs1(to);
  85.                 }
  86.             }
  87.             order[oSz++] = v;
  88.         }
  89.  
  90.         void dfs2(int v, int cl) {
  91.             comp[v] = cl;
  92.             for (int i = 0; i < gRev[v].length; i++) {
  93.                 int to = gRev[v][i];
  94.                 if (comp[to] == -1) {
  95.                     dfs2(to, cl);
  96.                 }
  97.             }
  98.         }
  99.  
  100.         boolean[] findSol() {
  101.             buildGraph();
  102.             int n = g.length;
  103.             order = new int[n];
  104.             used = new boolean[n];
  105.             comp = new int[n];
  106.             Arrays.fill(comp, -1);
  107.             q = new int[n];
  108.             it = new int[n];
  109.             for (int i = 0; i < n; i++) {
  110.                 if (!used[i]) {
  111.                     dfs1_nonRec(i);
  112.                 }
  113.             }
  114.             for (int i = 0, j = 0; i < n; ++i) {
  115.                 int v = order[n - i - 1];
  116.                 if (comp[v] == -1) {
  117.                     dfs2(v, j++);
  118.                 }
  119.             }
  120.  
  121.             for (int i = 0; i < n; ++i) {
  122.                 if (comp[i] == comp[i ^ 1]) {
  123.                     return null;
  124.                 }
  125.             }
  126.             boolean[] ans = new boolean[n / 2];
  127.             for (int i = 0; i < n; ++i) {
  128.                 ans[i / 2] = comp[i ^ 1] < comp[i];
  129.             }
  130.             return ans;
  131.         }
  132.  
  133.         String vertex(int v) {
  134.             return (v % 2 == 0 ? "!" : "") + Integer.toString(v / 2);
  135.         }
  136.  
  137.         void printGraph() {
  138.             for (int i = 0; i < g.length; i++) {
  139.                 for (int to : g[i]) {
  140.                     System.err.println(vertex(i) + " -> " + vertex(to));
  141.                 }
  142.             }
  143.         }
  144.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement