bingxuan9112

CF 1578 K

Nov 24th, 2021
947
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.76 KB | None | 0 0
  1. #pragma GCC optimize("Ofast")
  2. #pragma GCC target("popcnt")
  3. #pragma loop_opt(on)
  4. #include <bits/stdc++.h>
  5. #define pb emplace_back
  6.  
  7. using namespace std;
  8.  
  9. template <size_t maxn>
  10. struct MaximumIndependentSet {
  11.     using BS = bitset<maxn>;
  12.     BS g[maxn];
  13.     int ans;
  14.     BS ans_mask;
  15.     void addEdge(int a, int b) {
  16.         g[a][b] = g[b][a] = true;
  17.     }
  18.     BS solve(int n) {
  19.         ans = n;
  20.         BS select, alive;
  21.         for(int i = 0; i < n; i++) alive[i] = true;
  22.         dfs(0, select, alive);
  23.         return ~ans_mask;
  24.     }
  25.     void dfs(int c, BS select, BS alive) {
  26.         if (c > ans) return;
  27.         // reduce
  28.         int mx = -1, mxDeg = -1;
  29.         for (size_t i = alive._Find_first(); i < maxn; i = alive._Find_next(i)) {
  30.             int deg = (alive & g[i]).count();
  31.             if(deg == 1) {
  32.                 int j = (alive & g[i])._Find_first();
  33.                 alive[i] = alive[j] = false;
  34.                 select[j] = true;
  35.                 dfs(c+1, select, alive);
  36.                 return;
  37.             }
  38.             if(deg != 0 && deg > mxDeg)
  39.                 mx = i, mxDeg = deg;
  40.         }
  41.         if(mx == -1) {
  42.             if (ans > c)
  43.                 ans = c, ans_mask = select;
  44.             return;
  45.         }
  46.         alive[mx] = false;
  47.         select[mx] = true;
  48.         dfs(c+1, select, alive);
  49.         alive[mx] = true;
  50.         select[mx] = false;
  51.         BS adj = alive & g[mx];
  52.         dfs(c + adj.count(), select | adj, alive ^ adj);
  53.     }
  54. };
  55.  
  56. MaximumIndependentSet<80> qlig;
  57.  
  58. int main() {
  59.     ios_base::sync_with_stdio(false);
  60.     cin.tie(nullptr);
  61.     int C, n;
  62.     cin >> C >> n;
  63.     vector<int> s(n);
  64.     for (int i = 0; i < n; i++)
  65.         cin >> s[i], --s[i];
  66.     vector<vector<int>> this_color(C);
  67.     vector<bool> color_changed(C);
  68.     vector<bool> vertex_changed(n);
  69.     for (int i = 0; i < n; i++) {
  70.         this_color[s[i]].emplace_back(i);
  71.     }
  72.  
  73.     vector<int> vtx;
  74.     int k;
  75.     cin >> k;
  76.     vector<pair<int,int>> E;
  77.     for (int i = 0; i < k; i++) {
  78.         int a, b;
  79.         cin >> a >> b;
  80.         --a, --b;
  81.         color_changed[s[a]] = true;
  82.         color_changed[s[b]] = true;
  83.         vertex_changed[a] = true;
  84.         vertex_changed[b] = true;
  85.         vtx.emplace_back(a);
  86.         vtx.emplace_back(b);
  87.         E.emplace_back(a, b);
  88.         E.emplace_back(b, a);
  89.     }
  90.     sort(E.begin(), E.end());
  91.  
  92.  
  93.     vector<int> ans;
  94.     for (int i = 0; i < C; i++) {
  95.         if (color_changed[i]) {
  96.             int x = -1;
  97.             for (int y: this_color[i])
  98.                 if (!vertex_changed[y]) {
  99.                     x = y;
  100.                     break;
  101.                 }
  102.             if (x != -1)
  103.                 vtx.emplace_back(x);
  104.         } else {
  105.             if (this_color[i].size() > 0) {
  106.                 ans.emplace_back(this_color[i][0]);
  107.             }
  108.         }
  109.     }
  110.  
  111.     sort(vtx.begin(), vtx.end());
  112.     vtx.erase(unique(vtx.begin(), vtx.end()), vtx.end());
  113.  
  114.     int V = vtx.size();
  115.  
  116.     assert(V <= 80);
  117.     // qlig.init(V);
  118.     for (int i = 0; i < V; i++) {
  119.         for (int j = 0; j < i; j++) {
  120.             int x = vtx[i], y = vtx[j];
  121.             bool hasEdge =
  122.                 binary_search(E.begin(), E.end(),
  123.                         make_pair(x, y));
  124.             if ((s[x] == s[y]) ^ hasEdge) {
  125.                 // cerr << "addedge " << x << ',' << y << endl;
  126.                 qlig.addEdge(i, j);
  127.             }
  128.         }
  129.     }
  130.  
  131.     auto msk = qlig.solve(V);
  132.     // cerr << msk << endl;
  133.     for (int i = 0; i < V; i++) {
  134.         if (msk[i]) {
  135.             ans.emplace_back(vtx[i]);
  136.         }
  137.     }
  138.  
  139.     cout << ans.size() << '\n';
  140.     for (int i = 0; i < (int)ans.size(); i++) {
  141.         cout << ans[i]+1 << " \n"[i+1 == (int)ans.size()];
  142.     }
  143. }
Advertisement
Add Comment
Please, Sign In to add comment