Advertisement
Guest User

Untitled

a guest
Oct 1st, 2021
565
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.47 KB | None | 0 0
  1. //雪花飄飄北風嘯嘯
  2. //天地一片蒼茫
  3.  
  4. #include <bits/stdc++.h>
  5. #include <ext/pb_ds/assoc_container.hpp>
  6. #include <ext/pb_ds/tree_policy.hpp>
  7. #include <ext/rope>
  8. using namespace std;
  9. using namespace __gnu_pbds;
  10. using namespace __gnu_cxx;
  11. #define ll long long
  12. #define ii pair<ll,ll>
  13. #define iii pair<ii,ll>
  14. #define fi first
  15. #define se second
  16. #define endl '\n'
  17. #define debug(x) cout << #x << ": " << x << endl
  18.  
  19. #define pub push_back
  20. #define pob pop_back
  21. #define puf push_front
  22. #define pof pop_front
  23. #define lb lower_bound
  24. #define ub upper_bound
  25.  
  26. #define rep(x,start,end) for(auto x=(start)-((start)>(end));x!=(end)-((start)>(end));((start)<(end)?x++:x--))
  27. #define all(x) (x).begin(),(x).end()
  28. #define sz(x) (int)(x).size()
  29.  
  30. #define indexed_set tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>
  31. //change less to less_equal for non distinct pbds, but erase will bug
  32.  
  33. mt19937 rng(chrono::system_clock::now().time_since_epoch().count());
  34.  
  35.  
  36. // Complexity is 2^n or 2^(n/2) or something like this
  37. // if you need this it will probably pass
  38. // uncoment if n > 64
  39. // Usage: MaxClique mc; mc.init(vertices); mc();
  40. #define maxn 64
  41. // #define uint64_t bitset<maxn>
  42. // #define pcount(k) (k).count()
  43. // #define ctz(k) (k)._Find_first()
  44. #define pcount __builtin_popcountll
  45. #define ctz(k) __builtin_ctzll(k&-k)
  46.  
  47. struct MaxClique {
  48.     int n, deg[maxn];
  49.     uint64_t adj[maxn], ans;
  50.     vector<pair<int, int>> edge;
  51.     void init(int n_) {
  52.         n = n_;
  53.         fill(adj, adj + n, 0);
  54.         fill(deg, deg + n, 0);
  55.         edge.clear();
  56.     }
  57.     void add_edge(int u, int v) {
  58.         edge.emplace_back(u, v);
  59.         ++deg[u], ++deg[v];
  60.     }
  61.     vector<int> operator()() {
  62.         vector<int> ord(n);
  63.         iota(ord.begin(), ord.end(), 0);
  64.         sort(ord.begin(), ord.end(), [&](int u, int v) { return deg[u] < deg[v]; });
  65.         vector<int> id(n);
  66.         for (int i = 0; i < n; ++i) id[ord[i]] = i;
  67.         for (auto e : edge) {
  68.             int u = id[e.first], v = id[e.second];
  69.             adj[u] |= uint64_t(1)<<v;
  70.             adj[v] |= uint64_t(1)<<u;
  71.         }
  72.         uint64_t r(0), p(1);
  73.         p = (p<<n)-1;
  74.         // for( int i = 0 ; i < n ; ++i ) p.set(i);
  75.         ans = 0;
  76.         dfs(r, p);
  77.         vector<int> res;
  78.         for (int i = 0; i < n; ++i) {
  79.             if ((ans>>i&uint64_t(1))/*.count()*/) res.push_back(ord[i]);
  80.         }
  81.         return res;
  82.     }
  83.     void dfs(uint64_t r, uint64_t p) {
  84.         if (p == 0) {
  85.             if (pcount(r) > pcount(ans)) ans = r;
  86.             return;
  87.         }
  88.         if (pcount(r|p) <= pcount(ans)) return;
  89.         int x = ctz(p);
  90.         uint64_t c = p & ~adj[x];
  91.         while (c/*.count()*/ > 0) {
  92.             x = ctz(c);
  93.             uint64_t xmask(1);
  94.             xmask <<= x;
  95.             r |= xmask;
  96.             dfs(r, p & adj[x]);
  97.             r &= ~(xmask);
  98.             p &= ~(xmask);
  99.             c ^= (xmask);
  100.         }
  101.     }
  102. };
  103.  
  104. struct small_graph{
  105.     vector<vector<bool>> adj;
  106.     int n;
  107.     small_graph(int n) : n(n), adj(n, vector<bool>(n)){}
  108.     void add_edge(int u, int v){
  109.         adj[u][v] = adj[v][u] = true;
  110.     }
  111.     vector<int> MIS(){
  112.         MaxClique mc;
  113.         mc.init(n);
  114.         for(int i = 0; i < n; i++) for(int j = i + 1; j < n; j++) if(!adj[i][j]){
  115.             mc.add_edge(i, j);
  116.         }
  117.         return mc();
  118.     }
  119. };
  120.  
  121. int n,m,k;
  122. int arr[100005];
  123. vector<int> al[10005];
  124. vector<int> id[10005];
  125.  
  126. set<ii> op;
  127.  
  128. int extra[10005];
  129. bool has[100005];
  130.  
  131. bool vis[10005];
  132.  
  133. vector<int> ans;
  134.  
  135. vector<int> is;
  136. void dfs(int i){
  137.     vis[i]=true;
  138.    
  139.     for (auto &it:id[i]) is.pub(it);
  140.     if (extra[i]!=-1) is.pub(extra[i]);
  141.    
  142.     for (auto &it:al[i]){
  143.         if (vis[it]) continue;
  144.         dfs(it);
  145.     }
  146. }
  147.  
  148. int main(){
  149.     ios::sync_with_stdio(0);
  150.     cin.tie(0);
  151.     cout.tie(0);
  152.     cin.exceptions(ios::badbit | ios::failbit);
  153.    
  154.     cin>>m>>n;
  155.     rep(x,1,n+1) cin>>arr[x];
  156.    
  157.     cin>>k;
  158.    
  159.     int a,b;
  160.     rep(x,0,k){
  161.         cin>>a>>b;
  162.        
  163.         if (!has[a]){
  164.             id[arr[a]].pub(a);
  165.             has[a]=true;
  166.         }
  167.         if (!has[b]){
  168.             id[arr[b]].pub(b);
  169.             has[b]=true;
  170.         }
  171.        
  172.         op.insert(ii(a,b));
  173.         op.insert(ii(b,a));
  174.        
  175.         al[arr[a]].pub(arr[b]);
  176.         al[arr[b]].pub(arr[a]);
  177.     }
  178.    
  179.     memset(extra,-1,sizeof(extra));
  180.     rep(x,1,n+1) if (!has[x]) extra[arr[x]]=x;
  181.    
  182.     //rep(x,1,m+1) cout<<extra[x]<<" "; cout<<endl;
  183.    
  184.     rep(x,1,m+1) if (!vis[x]){
  185.         is.clear();
  186.        
  187.         dfs(x);
  188.        
  189.         //cout<<"hi"<<endl;
  190.         //for (auto &it:is) cout<<it<<" "; cout<<endl;
  191.        
  192.         small_graph g=small_graph(sz(is));
  193.         rep(i,0,sz(is)) rep(j,i+1,sz(is)){
  194.             bool add=(arr[is[i]]==arr[is[j]]);
  195.             if (op.count(ii(is[i],is[j]))) add^=true;
  196.            
  197.             if (add) g.add_edge(i,j);
  198.         }
  199.        
  200.         auto temp=g.MIS();
  201.         for (auto &it:temp) ans.pub(is[it]);
  202.     }
  203.    
  204.     cout<<sz(ans)<<endl;
  205.     for (auto &it:ans) cout<<it<<" "; cout<<endl;
  206. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement