歌名 - 歌手
0:00

    【ZJOJ1321】灯

    题目

    贝希和她的闺密们在她们的牛棚中玩游戏。但是天不从人愿,突然,牛棚的电源跳闸了,所有的灯都被关闭了。贝希是一个很胆小的女生,在伸手不见拇指的无尽的黑暗中,她感到惊恐,痛苦与绝望。她希望您能够帮帮她,把所有的灯都给重新开起来!她才能继续快乐地跟她的闺密们继续玩游戏!
      牛棚中一共有N(1 <= N <= 35)盏灯,编号为1到N。这些灯被置于一个非常复杂的网络之中。有M(1 <= M <= 595)条很神奇的无向边,每条边连接两盏灯。
      每盏灯上面都带有一个开关。当按下某一盏灯的开关的时候,这盏灯本身,还有所有有边连向这盏灯的灯的状态都会被改变。状态改变指的是:当一盏灯是开着的时候,这盏灯被关掉;当一盏灯是关着的时候,这盏灯被打开。
      问最少要按下多少个开关,才能把所有的灯都给重新打开。
      数据保证至少有一种按开关的方案,使得所有的灯都被重新打开。

    分析

    发现,当我们打开一个开关,就会取反一些灯的状态:0/1;
    对于第i个开关,就可以有一个对其他灯是否有影响的n位的二进制数。
    一开始,所有灯的状态为0,
    现在要让他全部变为1,即\(2^n-1\)
    题目就转化为,n个二进制数,如何取最少的数使他们的异或中为\(2^n-1\)
    观察数据范围\(n\le35\)
    直接枚举每个数选不选显然会超时。
    考虑,我们每次只枚举n/2个,
    先枚举前n/2个,将所有组合出的异或值扔进一个hash,或C++的map中(后者有点慢,为了方便,我打了map)
    再枚举剩下的,所有组合出的异或值与\(2^n-1\)异或一下,将异或出来的值看一下map中有没有,如果有,则与ans取min。

    #include <cmath>
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <map>
    const int maxlongint=2147483647;
    const int mo=1000000007;
    const long long N=45;
    using namespace std;
    int n,m,ans,tot;
    long long a[N],mi[N];
    map<long long,int> arr;
    void dg(int y,long long v,int dis)
    {
    	if(dis>ans) return;
    	if(v==mi[n]-1) ans=min(ans,dis);
    	else
    	{
    		if(arr[v]==0) arr[v]=dis;
    		else arr[v]=min(arr[v],dis);
    	}
    	if(y>n) return;
    	for(int i=y;i<=n;i++) dg(i+1,v^a[i],dis+1);
    }
    void dg1(int y,long long v,int dis)
    {
    	if(dis>ans) return;
    	if(v==mi[n]-1) ans=min(ans,dis);
    	else
    	{
    		tot++;
    		if(arr[(mi[n]-1)^v]!=0) ans=min(arr[(mi[n]-1)^v]+dis,ans);
    	}
    	if(y>n/2) return;
    	for(int i=y;i<=n/2;i++) dg1(i+1,v^a[i],dis+1);
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	mi[0]=1;
    	for(int i=1;i<=36;i++) mi[i]=mi[i-1]*2,a[i]=mi[i-1];
    	for(int i=1,x,y;i<=m;i++)
    	{
    		scanf("%d%d",&x,&y);
    		a[x]+=mi[y-1];
    		a[y]+=mi[x-1];
    	}
    	ans=maxlongint;
    	dg(n/2+1,0,0);
    	arr[0]=0;
    	dg1(1,0,0);
    	printf("%d",ans);
    }
    
    posted @ 2018-05-22 12:16  无尽的蓝黄  阅读(309)  评论(0编辑  收藏  举报