poj 1681 Painter's Problem 【高斯消元 枚举自由变元】

来源:互联网 发布:虚拟机 网络设置 编辑:程序博客网 时间:2024/05/17 01:48

链接:http://poj.org/problem?id=1681

题意:与poj1222相似 输出变为求最小步数。

分析:由于求最小步数,当我们存在自由变元时,我们可以得到解,但是不知道需要的最小步数,所以我们枚举所有的变元。

代码:

#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<string>#include<vector>#include<queue>#include<cmath>#include<stack>#include<set>#include<map>#define INF 0x3f3f3f3f#define Mn 230#define Mm 2000005#define mod 1000000007#define CLR(a,b) memset((a),(b),sizeof((a)))#define CLRS(a,b,Size) memset((a),(b),sizeof((a[0]))*(Size+1))#define CPY(a,b) memcpy ((a), (b), sizeof((a)))#pragma comment(linker, "/STACK:102400000,102400000")#define ul u<<1#define ur (u<<1)|1using namespace std;typedef long long ll;int a[Mn][Mn];int x[Mn];int free_x[Mn];int var,equ;int gauss() {    int k,col,max_r,cnt=0;    for(col=0,k=0;k<equ&&col<var;k++,col++) {        max_r=k;        for(int i=k+1;i<equ;i++)            if(abs(a[i][col])>abs(a[max_r][col])) max_r=i;        if(max_r!=k)            for(int j=col;j<=var;j++) swap(a[k][j],a[max_r][j]);        if(a[k][col]==0) {            k--;            free_x[cnt++]=col;            continue;        }        for(int i=k+1;i<equ;i++) {            if(a[i][col]) {                for(int j=col;j<=var;j++) {                    a[i][j]^=a[k][j];                }            }        }    }    for(int i=k;i<equ;i++) {        if(a[i][col]) return -1;    }    int res=INF;    for(int s=0;s<(1<<cnt);s++) {        int num=0;        int s0=s;        for(int i=0;i<cnt;i++) {            if(x[free_x[i]]=s0&1) num++;            s0>>=1;        }        for(int i=k-1;i>=0;i--) {            int tmp=a[i][var];            for(int j=i+1;j<var;j++) {                tmp^=(a[i][j]&&x[j]);            }            if(x[i]=tmp) num++;        }        res=min(res,num);    }    return res;}int n;void init() {    CLR(a,0);    var=n*n,equ=n*n;    for(int i=0;i<n;i++) {        for(int j=0;j<n;j++) {            int k=i*n+j;            a[k][k]=1;            if(i>0) a[k-n][k]=1;            if(i<n-1) a[k+n][k]=1;            if(j>0) a[k-1][k]=1;            if(j<n-1) a[k+1][k]=1;        }    }}int main() {    int t;    scanf("%d",&t);    for(int cas=1;cas<=t;cas++) {        scanf("%d",&n);        init();        for(int i=0;i<n;i++) {            getchar();            for(int j=0;j<n;j++) {                char c=getchar();                if(c=='w') a[i*n+j][n*n]=1;            }        }        int ans=gauss();        if(ans==-1) printf("inf\n");        else printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击