joylintp

P Clique

Jan 11th, 2022
762
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.06 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. #include"ypglpk.hpp"
  3. using namespace std;
  4. using namespace ypglpk;
  5.  
  6. //{
  7. //#pragma gcc optimize("Ofast,unroll-loops")
  8. //#pragma gcc target("sse,sse2,sse3,ssse3,sse4,avx,avx2,fma,abm,mmx,popcnt,tune=native")
  9. //#define int long long
  10. //#define double long double
  11. #define MP make_pair
  12. #define F first
  13. #define S second
  14. #define MOD 1000000007
  15. //}
  16.  
  17. vector<bitset<80>> edge, mxclq;
  18.  
  19. void solve(bitset<80> R, bitset<80> P, bitset<80> X, int N)
  20. {
  21.     if (P.none() && X.none())
  22.         mxclq.push_back(R);
  23.     else
  24.     {
  25.         int u = -1;
  26.         for (int i = 0; i < N; i++)
  27.             if ((P[i] || X[i]) && (u == -1 || edge[i].count() > edge[u].count()))
  28.                 u = i;
  29.  
  30.         bitset<80> Pp = P & (~edge[u]);
  31.         for (int i = 0; i < N; i++)
  32.             if (Pp[i])
  33.             {
  34.                 bitset<80> v;
  35.                 v[i] = true;
  36.  
  37.                 solve(R | v, P & edge[i], X & edge[i], N);
  38.                 P = P & ~v;
  39.                 X = X | v;
  40.             }
  41.     }
  42. }
  43.  
  44. signed main()
  45. {
  46.     ios_base::sync_with_stdio(false);
  47.     cin.tie(0);
  48.  
  49.     int T;
  50.     cin >> T;
  51.     while (T--)
  52.     {
  53.         int N, M;
  54.         cin >> N >> M, edge.resize(N);
  55.         for (int i = 0; i < N; i++)
  56.             edge[i].reset();
  57.  
  58.         for (int i = 0; i < M; i++)
  59.         {
  60.             int u, v;
  61.             cin >> u >> v;
  62.             edge[u][v] = edge[v][u] = true;
  63.         }
  64.  
  65.         bitset<80> R, P, X;
  66.         for (int i = 0; i < N; i++)
  67.             P[i] = true;
  68.         mxclq.clear(), solve(R, P, X, N);
  69.  
  70.         int C = mxclq.size(), NC = N * C;
  71.         vector<vector<double>> A;
  72.         vector<double> B;
  73.  
  74.         // 0 <= x[i][j] <= 1, 0 <= z[i] <= 1
  75.         for (int i = 0; i < NC + C; i++)
  76.         {
  77.             vector<double> tv(NC + C);
  78.             tv[i] = -1, A.push_back(tv), B.push_back(0);
  79.             tv[i] = 1, A.push_back(tv), B.push_back(1);
  80.         }
  81.  
  82.         // x[i][j] <= 0 if i is not in clique j
  83.         for (int i = 0; i < N; i++)
  84.             for (int j = 0; j < C; j++)
  85.                 if (!mxclq[j][i])
  86.                 {
  87.                     vector<double> tv(NC + C);
  88.                     tv[i * C + j] = 1, A.push_back(tv), B.push_back(0);
  89.                 }
  90.  
  91.         // x[i][j] <= z[j]
  92.         for (int i = 0; i < N; i++)
  93.             for (int j = 0; j < C; j++)
  94.             {
  95.                 vector<double> tv(NC + C);
  96.                 tv[i * C + j] = 1, tv[NC + j] = -1;
  97.                 A.push_back(tv), B.push_back(0);
  98.             }
  99.  
  100.         // for 0 <= j < C, sum(x[i][j]) = 1
  101.         for (int i = 0; i < N; i++)
  102.         {
  103.             vector<double> tv(NC + C);
  104.             for (int j = 0; j < C; j++)
  105.                 tv[i * C + j] = 1;
  106.             A.push_back(tv), B.push_back(1);
  107.             for (int j = 0; j < C; j++)
  108.                 tv[i * C + j] = -1;
  109.             A.push_back(tv), B.push_back(-1);
  110.         }
  111.  
  112.         // minimize sum(z[i]) -> maximize -sum(z[i])
  113.         vector<double> c(NC + C);
  114.         for (int i = 0; i < C; i++)
  115.             c[NC + i] = -1;
  116.  
  117.         pair<double, vector<double>> res = mixed_integer_linear_programming(A, B, c, vector<bool>(NC + C, true));
  118.         cout << -res.F << '\n';
  119.         for (int i = 0; i < C; i++)
  120.             if (res.S[NC + i])
  121.             {
  122.                 vector<int> v;
  123.                 for (int j = 0; j < N; j++)
  124.                     if (res.S[j * C + i])
  125.                         v.push_back(j);
  126.  
  127.                 cout << v.size();
  128.                 for (int j : v)
  129.                     cout << ' ' << j;
  130.                 cout << '\n';
  131.             }
  132.     }
  133.  
  134.     return 0;
  135. }
  136.  
  137. //      *****  *****  *   *  *      *****  *   *  *****  *****
  138. //        *   *   *  *   *  *        *    **  *    *    *   *
  139. //       *   *   *  *****  *        *    * * *    *    *****
  140. //   *  *   *   *    *    *        *    *  **    *    *
  141. //  ****   *****    *    *****  *****  *   *    *    *
  142.  
  143. //     *   *   ***   *   *  **
  144. //    *   *  *   *  *   *  **
  145. //   * * *  *****  *****  **
  146. //  * * *  *   *  *   *
  147. //  * *   *   *  *   *  **
  148.  
Advertisement
Add Comment
Please, Sign In to add comment