BZOJ3149 CTSC2013 复原 搜索
\(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;
}