[BZOJ2466][中山市选2009]树(高斯消元+dfs)

来源:互联网 发布:java lucene 教程 编辑:程序博客网 时间:2024/05/22 01:47

题目描述

传送门

题解

开关灯问题。。。

代码

#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<bitset>#include<cmath>using namespace std;#define N 105int n,x,y,now,Min;int tot,point[N],nxt[N*2],v[N*2];bitset <N> a[N];int b[N],ans[N];void clear(){    x=y=now=Min=0;    tot=0;memset(point,0,sizeof(point));    for (int i=1;i<=n;++i) a[i].reset();    memset(b,0,sizeof(b));memset(ans,0,sizeof(ans));}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;    for (int i=dep+1;i<=n;++i)        if (a[dep][i]) b[dep]^=ans[i];    if (a[dep][dep])    {        ans[dep]=b[dep];        if (ans[dep]) ++now;        dfs(dep-1);        if (ans[dep]) --now;    }    else    {        ans[dep]=0;        dfs(dep-1);        ans[dep]=1;++now;        dfs(dep-1);        ans[dep]=0;--now;    }    for (int i=dep+1;i<=n;++i)        if (a[dep][i]) b[dep]^=ans[i];}void gauss(){    for (int i=1;i<=n;++i)    {        if (!a[i][i])        {            for (int j=i+1;j<=n;++j)                if (a[j][i]) {a[i]^=a[j];b[i]^=b[j];break;}        }        for (int j=i+1;j<=n;++j)            if (a[j][i]) a[j]^=a[i],b[j]^=b[i];    }    dfs(n);}int main(){    while (~scanf("%d",&n))    {        if (!n) break;        clear();        for (int i=1;i<n;++i)        {            scanf("%d%d",&x,&y);            add(x,y),add(y,x);        }        for (int i=1;i<=n;++i)        {            a[i][i]=1;b[i]=1;            for (int j=point[i];j;j=nxt[j])                a[i][v[j]]=1;        }        Min=2100000000;gauss();        printf("%d\n",Min);    }}
0 0
原创粉丝点击