BZOJ繁体字看着很。。不爽啊。。
异或方程组。
最开始没有考虑自由元。
我想每一个地方都有个1,那肯定没有自由元...囧
然后由于自由元的存在,枚举自由元的选择方法。
#include <cstdio>
#include <algorithm>
#define rep(i,l,r) for (int i=l;i<=r;++i)
#define per(i,r,l) for (int i=r;i>=l;--i)
const int MAX_N=40;
bool a[MAX_N][MAX_N];
int n,m;
void gauss(){//可以压位
rep(i,1,n){
rep(j,i,n) if (a[j][i]>a[i][i]) rep(k,1,n+1) std::swap(a[i][k],a[j][k]);
rep(j,1,n) if (i!=j&&a[j][i]) rep(k,i,n+1) a[j][k]^=a[i][k];
}
}
int ans=100;
bool x[MAX_N];
void dfs(int v,int tot){//枚举自由元
if (tot>ans) return;
if (v<=0){ans=tot;return;}
if (a[v][v]){
x[v]=a[v][n+1];
rep(k,v+1,n) x[v]^=a[v][k]&x[k];
dfs(v-1,tot+x[v]);
}else{
x[v]=1;dfs(v-1,tot+1);
x[v]=0;dfs(v-1,tot);
}
}
int main(){
freopen("lights.in","r",stdin);
freopen("lights.out","w",stdout);
scanf("%d%d",&n,&m);
rep(i,1,n) a[i][i]=a[i][n+1]=1;
rep(i,1,m){
int x,y;scanf("%d%d",&x,&y);
a[x][y]=a[y][x]=1;
}
gauss();
dfs(n,0);
printf("%d\n",ans);
}