BZOJ3149 CTSC2013 復原 搜索、最大團
阿新 • • 發佈:2019-01-26
amp sar size spa tin ctsc ace eof times
傳送門
\(N \leq 20\)很適合暴搜……
第二問最大獨立集裸題,\(O(2^NN)\)的算法都能過……
考慮第一問,使用搜索尋找可行解
每一次枚舉一條弦的兩個端點,通過位運算計算與其相交的弦的數量進行剪枝
一些其他的剪枝:
①兩個非\(0\)值中間的所有\(0\)的地位是一樣的,所以可以將這些\(0\)縮成一個\(0\)
②每一個連通塊分別考慮,可以避免大量的重復情況
#include<bits/stdc++.h> //This code is written by Itst using namespace std; inline int read(){ int a = 0; char c = getchar(); bool f = 0; while(!isdigit(c) && c != EOF){ if(c == ‘-‘) f = 1; c = getchar(); } if(c == EOF) exit(0); while(isdigit(c)){ a = a * 10 + c - 48; c = getchar(); } return f ? -a : a; } bitset < 23 > Edge[23] , cur , ans; int arr[41] , ansArr[41] , times[21] , ind[21] , N , M , len , cntInd , cntA; bool vis[41]; queue < int > q; bool dfs1(int x){ if(x > cntInd) return 1; bitset < 23 > tmp; for(int i = 1 ; i < x ; ++i) tmp |= 1 << ind[i]; ++len; for(int i = len ; i > 1 ; --i) arr[i] = arr[i - 1]; for(int i = 1 ; i <= len ; ++i){ arr[i] = ind[x]; ++len; for(int j = len ; j > i + 1 ; --j) arr[j] = arr[j - 1]; bitset < 23 > p; p.set(); for(int j = i + 1 ; j <= len ; ++j){ arr[j] = ind[x]; if((p & tmp) == (Edge[ind[x]] & tmp) && dfs1(x + 1)) return 1; arr[j] = arr[j + 1]; p[arr[j]] = p[arr[j]] ^ 1; } --len; arr[i] = arr[i + 1]; } --len; return 0; } void dfs2(int x){ if(cur.count() + x <= ans.count()) return; if(!x) ans = cur; if((Edge[x] & cur) == cur){ cur.set(x); dfs2(x - 1); cur.reset(x); } dfs2(x - 1); } int main(){ #ifndef ONLINE_JUDGE freopen("in","r",stdin); freopen("out","w",stdout); #endif N = read(); M = read(); for(int i = 1 ; i <= N ; ++i){ Edge[i].set(); ind[i] = i; } for(int i = 1 ; i <= M ; ++i){ int a = read() , b = read(); Edge[a][b] = Edge[b][a] = 0; } for(int i = 1 ; i <= N ; ++i) if(!vis[i]){ vis[i] = 1; q.push(i); ind[cntInd = 1] = i; while(!q.empty()){ int t = q.front(); q.pop(); for(int j = 1 ; j <= N ; ++j) if(!vis[j] && !Edge[t][j]){ vis[j] = 1; q.push(j); ind[++cntInd] = j; } } memset(arr , 0 , sizeof(arr)); if(dfs1(1)) for(int j = 1 ; j <= cntInd * 2 ; ++j) ansArr[++cntA] = arr[j]; } for(int i = 1 ; i <= N * 2 ; ++i) cout << ansArr[i] << ‘ ‘; cout << endl; cur.reset(); dfs2(N); cout << ans.count(); return 0; }
BZOJ3149 CTSC2013 復原 搜索、最大團