所谓状态压缩,大多数就是用二进制01形式将状态表示出来,运用位运算完成状态的查看和转移;基本上数据范围是n<=15;
这是很裸的状态压缩。我们要关闭所有的开关,但是开关是相连的;
有一个很好地条件是,开关最多能波及到两层;一个开关的变化,直接关联的会变化,间接变化的也会变,但是间接变化的不会再传递下去;
所以我们将每个开关关掉后的状态记录下来;
设二进制1是关闭状态,当状态变为0时更新答案即可;
要排除自己关自己的情况;
二进制枚举关哪一个就行了;
一个开关不需要关两遍及以上,相当于没干什么;
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=1e6+10; int res[maxn]; int a[30][30]; int n; int ans=2147483647; void dfs(int x,int now,int cnt) { if(x==n+1) { if(now==0) { ans=min(ans,cnt); } return ; } dfs(x+1,now,cnt); now^=res[x]; dfs(x+1,now,cnt+1); now^=res[x]; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { int m; scanf("%d",&m); for(int j=1;j<=m;j++) { int x; scanf("%d",&x); a[i][x]=1; } } for(int i=1;i<=n;i++) { res[i]^=(1<<i); for(int j=1;j<=n;j++) { if(a[i][j]&&i!=j) { res[i]^=(1<<j); for(int k=1;k<=n;k++) { if(a[j][k]&&j!=k) { res[i]^=(1<<k); } } } } } //int sum=0; int sum=(1<<(n+1))-2; /*for(int i=1;i<=n;i++) { sum+=1<<i; }*/ //printf("%d\n",sum); dfs(1,sum,0); if(ans==2147483647) printf("Change an alarm clock,please!"); else printf("%d",ans); return 0; }