bzoj 2466

裸的高斯消元解异或方程组问题

对于每个点列一个异或方程,所有影响这个点的点的对应系数为1,然后高消解一下就好

自由元用dfs处理,注意剪枝

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n;
int a[105][105];
void Gauss()
{
    for(int i=1;i<=n;i++)
    {
        int temp=i;
        while(!a[temp][i]&&temp<=n)temp++;
        if(temp>n)continue;
        if(temp!=i)for(int j=i;j<=n+1;j++)swap(a[temp][j],a[i][j]);
        for(int j=1;j<=n;j++)if(a[j][i]&&j!=i)for(int k=i;k<=n+1;k++)a[j][k]^=a[i][k];
    }
}
int ans=0x3f3f3f3f;
void dfs(int dep,int sum)
{
    if(sum>=ans)return;
    if(!dep){ans=sum;return;}
    if(a[dep][dep])dfs(dep-1,sum+a[dep][n+1]);
    else
    {
        if(a[dep][n+1])return;
        dfs(dep-1,sum);
        for(int i=dep-1;i;i--)a[i][n+1]^=a[i][dep];
        dfs(dep-1,sum+1);
        for(int i=dep-1;i;i--)a[i][n+1]^=a[i][dep];
    }
}
int main()
{
    while(1)
    {
        scanf("%d",&n);
        memset(a,0,sizeof(a));
        if(!n)return 0;
        if(n==1){printf("1\n");continue;}
        int x,y;
        for(int i=1;i<n;i++)scanf("%d%d",&x,&y),a[x][y]=a[y][x]=a[i][n+1]=a[n][n+1]=a[i][i]=a[n][n]=1;
        Gauss();
        ans=0x3f3f3f3f;
        dfs(n,0);
        printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2019-05-06 20:50  lleozhang  Views(143)  Comments(0Edit  收藏  举报
levels of contents