• P2962 [USACO09NOV]灯Lights


    P2962 [USACO09NOV]灯Lights

    看完题面,我马上趁教练不注意 打开了某399小游戏。熟练地找到了这个游戏。颓废了一上午 就想到怎么做了。

    233

    对于一个灯和所以与他相连的等灯。每个灯只有按和不按两种情况。为什么呢? 如果同一盏灯按了两次。就跟没按时一样的。三次亦是如此。由此可得,按奇数次的效果等于按了一次,按偶数次等于没按。

    确定了这个关系,我们就可以使用位运算,异或进行列方程了。

    啥?方程?等等,smg?

    我们要求的是每个灯是否被按。

    这就是我们的未知数。

    我们设计一下系数,如果一盏灯对于其他的灯有影响,那么这盏灯所对应的未知数在被影响的灯的方程中就是一。如果某一盏灯对其他灯没有影响,他的系数就是0.(0异或任何数都是原数,对答案不产生影响)。

    又由于异或具有交换律和结合律。所以可以用来移项。


    而题目中是所问的是最少关多少盏灯灯全部打开所有灯。

    这就提示我们,有很大可能会出现自由元(就是可以任意取值的未知数)

    然后我们来看数据范围。

    (ok)

    位置数个数小于等于35.

    枚举全部状态肯定不行。

    不过如果只枚举自由元,再加上最优性剪枝,应该是可以跑过去的。

    233

    然后我是stl毒瘤选手。

    怎么能不用bitset呢

    另一道异或方程

    #include<iostream> 
    #include<cstdio>
    #include<algorithm>
    #include<bitset>
    using namespace std;
    bitset<38>g[38];
    int n,m;
    void gauss()
    {
    	for(int i=1;i<=n;i++)
    	{
    		int r=i;
    		for(int j=i+1;j<=n;j++)
    			if(g[j][i])
    			{
    				r=j;
    				break;
    			}
    		if(r!=i)
    			swap(g[i],g[r]);
    		for(int j=i+1;j<=n;j++)
    			if(g[j][i])
    				g[j]^=g[i];//bitset可以整体异或
    	}
    }
    int ans=0x7fffffff;
    int base[38];
    void dfs(int now,int sum)//就是回带,now就是回带到多少个了(n~1),sum为当前开的灯的数量
    {
    	if(sum>ans)
    		return ;
    	if(now==0)
    	{
    		ans=min(ans,sum);
    		return ;
    	}
    	if(g[now][now])
    	{
    		base[now]=g[now][n+1];
    		for(int i=now+1;i<=n;i++)
    			base[now]^=(base[i]&g[now][i]);//要乘系数。这里利用了与运算进行加速(为什么可以,可以自行枚举判断真确性)
    		if(base[now])//如果这个灯是开的
    			dfs(now-1,sum+1);
    		else
    			dfs(now-1,sum);
    	}
    	else//自由元
    	{
    		base[now]=0;
    		dfs(now-1,sum);
    		base[now]=1;
    		dfs(now-1,sum+1);//枚举一波
    	}
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	int a,b;
    	for(int i=1;i<=n;i++)
    		g[i][n+1]=g[i][i]=1;
    	for(int i=1;i<=m;i++)
    	{
    		scanf("%d%d",&a,&b);
    		g[a][b]=1;
    		g[b][a]=1;
    	}
    	gauss();
    	dfs(n,0);
    	printf("%d",ans);
    }
    
  • 相关阅读:
    【复习】数据库维护-索引语法
    C# 以管理员身份运行WinForm程序
    Postgresql死锁处理
    401 Not Authorized For MSDEPLOY‏ (msdeployAgentService)
    GIT使用指南
    redis使用指南
    nginx使用指南
    DB2日常维护常用命令
    AIX常用命令总结
    C语言+嵌入式SQL+DB2开发经验总结
  • 原文地址:https://www.cnblogs.com/Lance1ot/p/9062439.html
Copyright © 2020-2023  润新知