Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //雪花飄飄北風嘯嘯
- //天地一片蒼茫
- #include <bits/stdc++.h>
- #include <ext/pb_ds/assoc_container.hpp>
- #include <ext/pb_ds/tree_policy.hpp>
- #include <ext/rope>
- using namespace std;
- using namespace __gnu_pbds;
- using namespace __gnu_cxx;
- #define ll long long
- #define ii pair<ll,ll>
- #define iii pair<ii,ll>
- #define fi first
- #define se second
- #define endl '\n'
- #define debug(x) cout << #x << ": " << x << endl
- #define pub push_back
- #define pob pop_back
- #define puf push_front
- #define pof pop_front
- #define lb lower_bound
- #define ub upper_bound
- #define rep(x,start,end) for(auto x=(start)-((start)>(end));x!=(end)-((start)>(end));((start)<(end)?x++:x--))
- #define all(x) (x).begin(),(x).end()
- #define sz(x) (int)(x).size()
- #define indexed_set tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>
- //change less to less_equal for non distinct pbds, but erase will bug
- mt19937 rng(chrono::system_clock::now().time_since_epoch().count());
- // Complexity is 2^n or 2^(n/2) or something like this
- // if you need this it will probably pass
- // uncoment if n > 64
- // Usage: MaxClique mc; mc.init(vertices); mc();
- #define maxn 64
- // #define uint64_t bitset<maxn>
- // #define pcount(k) (k).count()
- // #define ctz(k) (k)._Find_first()
- #define pcount __builtin_popcountll
- #define ctz(k) __builtin_ctzll(k&-k)
- struct MaxClique {
- int n, deg[maxn];
- uint64_t adj[maxn], ans;
- vector<pair<int, int>> edge;
- void init(int n_) {
- n = n_;
- fill(adj, adj + n, 0);
- fill(deg, deg + n, 0);
- edge.clear();
- }
- void add_edge(int u, int v) {
- edge.emplace_back(u, v);
- ++deg[u], ++deg[v];
- }
- vector<int> operator()() {
- vector<int> ord(n);
- iota(ord.begin(), ord.end(), 0);
- sort(ord.begin(), ord.end(), [&](int u, int v) { return deg[u] < deg[v]; });
- vector<int> id(n);
- for (int i = 0; i < n; ++i) id[ord[i]] = i;
- for (auto e : edge) {
- int u = id[e.first], v = id[e.second];
- adj[u] |= uint64_t(1)<<v;
- adj[v] |= uint64_t(1)<<u;
- }
- uint64_t r(0), p(1);
- p = (p<<n)-1;
- // for( int i = 0 ; i < n ; ++i ) p.set(i);
- ans = 0;
- dfs(r, p);
- vector<int> res;
- for (int i = 0; i < n; ++i) {
- if ((ans>>i&uint64_t(1))/*.count()*/) res.push_back(ord[i]);
- }
- return res;
- }
- void dfs(uint64_t r, uint64_t p) {
- if (p == 0) {
- if (pcount(r) > pcount(ans)) ans = r;
- return;
- }
- if (pcount(r|p) <= pcount(ans)) return;
- int x = ctz(p);
- uint64_t c = p & ~adj[x];
- while (c/*.count()*/ > 0) {
- x = ctz(c);
- uint64_t xmask(1);
- xmask <<= x;
- r |= xmask;
- dfs(r, p & adj[x]);
- r &= ~(xmask);
- p &= ~(xmask);
- c ^= (xmask);
- }
- }
- };
- struct small_graph{
- vector<vector<bool>> adj;
- int n;
- small_graph(int n) : n(n), adj(n, vector<bool>(n)){}
- void add_edge(int u, int v){
- adj[u][v] = adj[v][u] = true;
- }
- vector<int> MIS(){
- MaxClique mc;
- mc.init(n);
- for(int i = 0; i < n; i++) for(int j = i + 1; j < n; j++) if(!adj[i][j]){
- mc.add_edge(i, j);
- }
- return mc();
- }
- };
- int n,m,k;
- int arr[100005];
- vector<int> al[10005];
- vector<int> id[10005];
- set<ii> op;
- int extra[10005];
- bool has[100005];
- bool vis[10005];
- vector<int> ans;
- vector<int> is;
- void dfs(int i){
- vis[i]=true;
- for (auto &it:id[i]) is.pub(it);
- if (extra[i]!=-1) is.pub(extra[i]);
- for (auto &it:al[i]){
- if (vis[it]) continue;
- dfs(it);
- }
- }
- int main(){
- ios::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
- cin.exceptions(ios::badbit | ios::failbit);
- cin>>m>>n;
- rep(x,1,n+1) cin>>arr[x];
- cin>>k;
- int a,b;
- rep(x,0,k){
- cin>>a>>b;
- if (!has[a]){
- id[arr[a]].pub(a);
- has[a]=true;
- }
- if (!has[b]){
- id[arr[b]].pub(b);
- has[b]=true;
- }
- op.insert(ii(a,b));
- op.insert(ii(b,a));
- al[arr[a]].pub(arr[b]);
- al[arr[b]].pub(arr[a]);
- }
- memset(extra,-1,sizeof(extra));
- rep(x,1,n+1) if (!has[x]) extra[arr[x]]=x;
- //rep(x,1,m+1) cout<<extra[x]<<" "; cout<<endl;
- rep(x,1,m+1) if (!vis[x]){
- is.clear();
- dfs(x);
- //cout<<"hi"<<endl;
- //for (auto &it:is) cout<<it<<" "; cout<<endl;
- small_graph g=small_graph(sz(is));
- rep(i,0,sz(is)) rep(j,i+1,sz(is)){
- bool add=(arr[is[i]]==arr[is[j]]);
- if (op.count(ii(is[i],is[j]))) add^=true;
- if (add) g.add_edge(i,j);
- }
- auto temp=g.MIS();
- for (auto &it:temp) ans.pub(is[it]);
- }
- cout<<sz(ans)<<endl;
- for (auto &it:ans) cout<<it<<" "; cout<<endl;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement