高斯消元模板

http://poj.org/problem?id=1753

View Code
struct GaussE {
    int a[MM][MM];
    int x[MM]; // 解集
    int equ, var;
    int free_x[MM]; // 记录不确定的变元.
    //初始化
    GaussE(int e,int v):equ(e), var(v) {}
    void reset() {
        memset(a,0,sizeof(a));
        memset(x,0,sizeof(x));
        memset(free_x,0,sizeof(free_x));
    }
    //重写(),方便存取
    int& operator() (int i,int j) {return a[i][j];}
    //debug
    void out() {
        int i,j,k;
        for(i=0;i<equ;i++)    {
            for(j=0;j<(var+1);j++) {
                printf("%d ",a[i][j]);
            }
            printf("\n");
        }
        printf("\n");
    }
// 有equ个方程,var个变元 增广阵行数为equ
//分别为0到equ-1,列数为var+1,分别为0到var.
//传入equ, var (var列存方程组的解)
    int Gauss() {
        int i,j,k,col,row,ta,tb, temp; 
        int max_r, LCM, ans, mm=0;
        int free_x_num, free_index, sum, tt;  

        for(row=col=0; row<equ && col<var; row++,col++) { 
            max_r=row;
            for(i=row+1;i<equ;i++) {
                if(f_abs(a[i][col])>f_abs(a[max_r][col])) max_r=i;
            }
            if(max_r!=row) {
                for(j=row; j<var+1; j++) swap(a[row][j],a[max_r][j]);
            }
            if(a[row][col]==0) { 
                row--; 
                free_x[mm++]=col;
                continue;
            }
            for(i=row+1; i<equ; i++) { 
                if(a[i][col]!=0) {
        //         LCM=lcm(f_abs(a[i][col]),f_abs(a[row][col]));
        //         ta=LCM/f_abs(a[i][col]), tb=LCM/f_abs(a[row][col]);
        //         if(a[i][col]*a[row][col]<0) tb=-tb; 
                for(j=col; j<var+1; j++) {
        //            a[i][j] = a[i][j] * ta - a[row][j] * tb;
                    a[i][j]^=a[row][j];
                 }
                }
            }
        }
       //无解
        for(i=row; i<equ; i++) if (a[i][col]!=0) return -1;
        //无穷解,变元个数为var-row
        if(row<var)  return var-row;     
        //唯一解
        return 0;
    }
    int gao(int row) {
        int i,j,k,sum,tt;
        int res=-1, state=1<<(var-row); //自由变元枚举
        for(i=0;i<state;i++) {
            sum=0, tt=i; 
            for(j=0;j<(var-row);j++) {
                x[free_x[j]]=(tt&1);
                sum+=x[free_x[j]];
                tt>>=1;
            }
            
            for(j=row-1;j>=0;j--) {
                x[j]=a[j][var];
                for(k=j+1;k<var;k++) {
                    if(a[j][k]!=0) x[j]^=x[k];
                }
                sum+=x[j];
            }
            if(res==-1||res>sum) res=sum;
        }
        return res;
    }
};

bool ok(int x,int y) {
    return x>=0 && x<N && y>=0 && y<N;
}

void get_data() {
    int i,j,k;
    N=4;
    for(i=0;i<N;i++) scanf("%s",str[i]);
}
void solve() {
    int i,j,k, limit=N*N, tmp, tx,ty, ans, ff;
    GaussE gauss(limit,limit);
    
    gauss.reset();
    for(i=0;i<N;i++) {
        for(j=0;j<N;j++) {
            tmp=i*N+j;
            gauss(tmp,limit)=(str[i][j]=='b');
            gauss(tmp,tmp)=1;
            for(k=0;k<4;k++) {
                tx=i+dx[k], ty=j+dy[k];
                if(ok(tx,ty)) gauss(tmp,tx*N+ty)=1;
            }
        }
    }
    ans=gauss.Gauss();
    if(ans!=-1) ans=gauss.gao(limit-ans);
    
    gauss.reset();
    for(i=0;i<N;i++) {
        for(j=0;j<N;j++) {
            tmp=i*N+j;
            gauss(tmp,limit)=(str[i][j]=='w');
            gauss(tmp,tmp)=1;
            for(k=0;k<4;k++) {
                tx=i+dx[k], ty=j+dy[k];
                if(ok(tx,ty)) gauss(tmp,tx*N+ty)=1;
            }
        }
    }
    tmp=gauss.Gauss();
    if(tmp!=-1) tmp=gauss.gao(limit-tmp);
    
    if(tmp==-1&&ans==-1) puts("Impossible");
    else {
        if(tmp>=0&&ans>=0) printf("%d\n",f_min(tmp,ans));
        else if(tmp==-1) printf("%d\n", ans);
        else printf("%d\n",tmp);
    }
}

int main() {
    //    int ca;  scanf("%d",&ca);
    get_data(),solve();
    return 0;
}

 

posted @ 2013-04-15 16:08  zhang1107  阅读(147)  评论(0编辑  收藏  举报