所谓状态压缩,大多数就是用二进制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; 
    
}
View Code

相关文章:

  • 2022-12-23
  • 2021-12-22
  • 2021-10-02
  • 2021-12-27
  • 2022-01-14
  • 2022-01-31
猜你喜欢
  • 2022-01-23
  • 2021-06-24
  • 2021-09-17
  • 2021-11-10
  • 2021-12-02
  • 2021-11-21
相关资源
相似解决方案