[BZOJ1770][Usaco2009 Nov]lights 燈(高斯消元)

来源:互联网 发布:gta5韩国美女捏脸数据 编辑:程序博客网 时间:2024/05/07 07:01

题目描述

传送门

题解

orz繁體中文
高斯消元解異或方程組
最後需要暴搜自由元
一定要加一个最简单的最优化剪枝,否则会tle…

代码

#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#include<bitset>using namespace std;int n,m,x,y,now,Min=35;int tot,point[40],nxt[1200],v[1200];int b[40],ans[40];bitset <40> a[40];void add(int x,int y){    ++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y;}void dfs(int dep){    if (!dep)    {        Min=min(Min,now);        return;    }    if (now>=Min) return;    if (a[dep][dep])    {        for (int i=dep+1;i<=n;++i)            if (a[dep][i]) b[dep]^=ans[i];        ans[dep]=b[dep];        if (ans[dep]) ++now;        dfs(dep-1);        if (ans[dep]) --now;        for (int i=dep+1;i<=n;++i)            if (a[dep][i]) b[dep]^=ans[i];    }    else    {        ans[dep]=0;        dfs(dep-1);        ans[dep]=1;        ++now;        dfs(dep-1);        --now;    }}void gauss(){    for (int i=1;i<=n;++i)    {        if (!a[i][i])        {            int num=i;            for (int j=i+1;j<=n;++j)                if (a[j][i]) {num=j;break;}            a[i]^=a[num],b[i]^=b[num];        }        for (int j=i+1;j<=n;++j)            if (a[j][i]) a[j]^=a[i],b[j]^=b[i];    }    dfs(n);}int main(){    scanf("%d%d",&n,&m);    for (int i=1;i<=m;++i)    {        scanf("%d%d",&x,&y);        add(x,y),add(y,x);    }    for (int i=1;i<=n;++i)    {        a[i][i]=b[i]=1;        for (int j=point[i];j;j=nxt[j])            a[i][v[j]]=1;    }    gauss();    printf("%d\n",Min);}
0 0
原创粉丝点击