题意:
貝希和她的閨密們在她們的牛棚中玩遊戲。但是天不從人願,突然,牛棚的電源跳閘了,所有的燈都被關閉了。貝希是一個很膽小的女生,在伸手不見拇指的無盡的黑暗中,她感到驚恐,痛苦與絕望。她希望您能夠幫幫她,把所有的燈都給重新開起來!她才能繼續快樂地跟她的閨密們繼續玩遊戲! 牛棚中一共有N(1 <= N <= 35)盞燈,編號為1到N。這些燈被置於一個非常複雜的網絡之中。有M(1 <= M <= 595)條很神奇的無向邊,每條邊連接兩盞燈。 每盞燈上面都帶有一個開關。當按下某一盞燈的開關的時候,這盞燈本身,還有所有有邊連向這盞燈的燈的狀態都會被改變。狀態改變指的是:當一盞燈是開著的時候,這盞燈被關掉;當一盞燈是關著的時候,這盞燈被打開。 問最少要按下多少個開關,才能把所有的燈都給重新打開。 數據保證至少有一種按開關的方案,使得所有的燈都被重新打開。
题解:
因为懒,所以不想概括题意
其实就是异或方程组。
对于自由元,一开始SB的以为无脑填0,要dfs一下,因为会影响其他x值。
code:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<bitset>
using namespace std;
bitset<40> a[40];
int n,m,Ans=100,ans[40];
void guess()
{
for(int i=1;i<=n;i++)
{
int j;
for(j=i;j<=n&&!a[j][i];j++);
if(j>n) continue;
swap(a[i],a[j]);
for(int k=i+1;k<=n;k++)
if(a[k][i]) a[k]=a[k]^a[i];
}
}
void dfs(int x,int tot)
{
if(tot>=Ans) return;
if(!x) {Ans=tot;return;}
if(a[x][x])
{
int t=a[x][n+1];
for(int i=x+1;i<=n;i++) t=t^(ans[i]*a[x][i]);
ans[x]=t;
dfs(x-1,tot+t);
}
else
{
ans[x]=0;dfs(x-1,tot);
ans[x]=1;dfs(x-1,tot+1);
}
}
int main()
{
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++)
{
int x,y;scanf("%d %d",&x,&y);
a[x][y]=a[y][x]=1;
}
for(int i=1;i<=n;i++) a[i][i]=a[i][n+1]=1;
guess();
dfs(n,0);
printf("%d",Ans);
}