Advertisement
Guest User

Untitled

a guest
May 11th, 2021
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.48 KB | None | 0 0
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <vector>
  4. #include <map>
  5. #include <set>
  6. #include <array>
  7. #include <stack>
  8. #include <queue>
  9. #include <random>
  10. #include <numeric>
  11. #include <functional>
  12. #include <chrono>
  13. #include <utility>
  14. #include <iomanip>
  15. #include <assert.h>
  16.  
  17. using namespace std;
  18.  
  19. void dbg_out() { cerr << endl; }
  20. template<typename Head, typename... Tail>
  21. void dbg_out(Head H, Tail... T) { cerr << ' ' << H; dbg_out(T...); }
  22. #define dbg(...) cerr << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
  23.  
  24. #define rng_init mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
  25. #define rng_seed(x) mt19937 rng(x)
  26. #define all(x) (x).begin(), (x).end()
  27. #define sz(x) (int) (x).size()
  28. // #define int long long
  29.  
  30. struct UFDS {
  31.     int n;
  32.     vector<int> info;
  33.  
  34.     UFDS() {}
  35.  
  36.     UFDS(int _n) { init(_n); }
  37.  
  38.     void init(int _n) {
  39.         n = _n;
  40.         info.assign(n, -1);
  41.     }
  42.  
  43.     int get(int x) {
  44.         if (info[x] < 0) return x;
  45.         return info[x] = get(info[x]);
  46.     }
  47.  
  48.     bool unite(int x, int y) {
  49.         x = get(x), y = get(y);
  50.         if (x == y) return false;
  51.  
  52.         if (info[x] > info[y])
  53.             swap(x, y);
  54.  
  55.         info[x] += info[y];
  56.         info[y] = x;
  57.  
  58.         return true;    
  59.     }
  60.  
  61.     bool connected(int x, int y) { return get(x) == get(y); }
  62. };
  63.  
  64. struct two_colouring {
  65.     int n;
  66.     UFDS ufds;
  67.     vector<int> answer, in_answer;
  68.  
  69.     two_colouring(int _n) { init(_n); }
  70.  
  71.     void init(int _n) {
  72.         n = _n;
  73.         ufds.init(2 * n);
  74.     }
  75.  
  76.     void add_clause_equal(int x, int y) {
  77.         ufds.unite(x, y);
  78.         ufds.unite(x + n, y + n);
  79.     }
  80.  
  81.     void add_clause_opposite(int x, int y) {
  82.         ufds.unite(x, y + n);
  83.         ufds.unite(x + n, y);
  84.     }
  85.  
  86.     bool satisfiable() {
  87.         for (int i = 0; i < n; i++)
  88.             if (ufds.connected(i, i + n)) return false;
  89.  
  90.         return true;
  91.     }
  92.    
  93.     // Construct an answer where we minimise the number of "which" values in each component
  94.     // which is either 1 or 0
  95.     void construct_answer(int which) {
  96.         answer.resize(n);
  97.         in_answer.assign(2 * n, 0);
  98.         vector<int> cnt(2 * n, 0);
  99.  
  100.         for (int i = 0; i < 2 * n; i++)
  101.             cnt[ufds.get(i)] += (i > n) ^ which;
  102.  
  103.         for (int i = 0; i < n; i++) {
  104.             int cur = ufds.get(i), complement = ufds.get(i + n);
  105.  
  106.             if (in_answer[cur] || in_answer[complement])
  107.                 continue;
  108.  
  109.             if (cnt[cur] < cnt[complement])
  110.                 in_answer[cur] = true;
  111.             else
  112.                 in_answer[complement] = true;
  113.         }
  114.  
  115.         for (int i = 0; i < n; i++)
  116.             answer[i] = (in_answer[ufds.get(i)] ? 1 : 0);
  117.     }
  118. };
  119.  
  120. const int MXN = 5e6 + 6, INF = 1e9 + 5;
  121.  
  122. void solve() {
  123.     int N, Q;
  124.     cin >> N >> Q;
  125.  
  126.     two_colouring solver(N);
  127.  
  128.     while (Q--) {
  129.         int type, u, v;
  130.         cin >> type >> u >> v;
  131.         u--, v--;
  132.  
  133.         if (type == 1) {
  134.             solver.add_clause_opposite(u, v);
  135.         } else {
  136.             solver.add_clause_equal(u, v);
  137.         }
  138.     }
  139.  
  140.     if (!solver.satisfiable()) {
  141.         cout << "-1\n";
  142.         return;
  143.     }
  144.  
  145.     solver.construct_answer(1);
  146.  
  147.     int ans = 0;
  148.     for (const auto &x : solver.answer)
  149.         ans += !x;
  150.  
  151.     cout << ans << "\n";
  152. }
  153.  
  154. signed main() {
  155.     ios_base::sync_with_stdio(false);
  156.     cin.tie(nullptr);
  157.  
  158.     int TC = 1;
  159.     cin >> TC;
  160.     while (TC--) solve();
  161. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement