【BZOJ2466】【中山市选2009】树 高斯消元解异或方程组

广告:

#include <stdio.h>
int main()
{
    puts("转载请注明出处[vmurder]谢谢");
    puts("网址:blog.csdn.net/vmurder/article/details/44356273");
}

题解:

参照此题解,也是我写的,俩题一样。
【POJ1681】Painter’s Problem 高斯消元,求最小∑系数的异或方程组

代码:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 105
#define inf 0x3f3f3f3f
using namespace std;

bool a[N][N],x[N];
int crs[N],n,ans;

void dfs(int id,int which,int now)
{
    if(id<1)
    {
        ans=min(ans,now);
        return ;
    }
    if(now>=ans)return ;

    if(crs[id]==which)
    {
        bool ret=a[id][n+1];
        for(int i=which+1;i<=n;i++)ret^=(a[id][i]*x[i]);
        x[which]=ret;
        dfs(id-1,which-1,now+ret);
    }
    else {
        x[which]=true;
        dfs(id,which-1,now+1);
        x[which]=false;
        dfs(id,which-1,now);
    }
    return ;
}

int Gauss(int n,int m)
{
    int i,j,k,id;
    for(id=i=1;i<n;i++,id++)
    {
        for(j=id;j<=m&&!a[j][i];j++);
        if(j>m){id--;continue;}

        crs[id]=i;
        if(id!=j)for(k=i;k<=n;k++)swap(a[id][k],a[j][k]);
        for(j=id+1;j<=m;j++)if(a[j][i])for(k=i;k<=n;k++)
            a[j][k]^=a[id][k];
    }
    for(i=id;i<=m;i++)if(a[i][n])return -1;
    return id-1;
}

int id[N][N],cnt;
char src[N];

void init()
{
    cnt=0,ans=inf;
    memset(a,0,sizeof a);
    memset(x,0,sizeof x);
    memset(id,0,sizeof id);
    memset(crs,0,sizeof crs);
}

int main()
{
    freopen("test.in","r",stdin);

    int i,j,k;
    int x,y,t;

    while(scanf("%d",&n),n)
    {
        init();
        for(i=1;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            a[x][y]=a[y][x]=1;
        }
        for(i=1;i<=n;i++)a[i][i]=a[i][n+1]=1;
        t=Gauss(n+1,n);
        if(t==-1)puts("inf");
        else {
            dfs(t,n,0);
            printf("%d\n",ans);
        }

    }
    return 0;
}

你可能感兴趣的:(树,高斯消元,异或方程组,BZOJ2466,中山市选2009)