实数版:O(n^3)
解方程:
#include <cstdio>
#include <algorithm>
#define rep(i,l,r) for (int i=l;i<=r;++i)
const double EPS=1e-8;
int sign(const double &x){return x<-EPS?-1:x>EPS;}
const int MAX_N=105,MAX_M=1005;
double a[MAX_N][MAX_M+MAX_N];
int n,m;
void gauss(){
rep(i,1,n){
int p=1;
rep(j,i,n) if (sign(a[j][i])){p=j;break;} //这里应该写成绝对值最大的精度高一些
rep(k,1,n+m) std::swap(a[i][k],a[p][k]);
rep(j,1,n) if (i!=j){
double r=a[j][i]/a[i][i];
rep(k,i,n+m) a[j][k]-=r*a[i][k];
}
}
rep(i,n+1,n+m) rep(j,1,n)
printf("%.3f%c",a[j][i]/a[j][j],j==n?'\n':' ');
}
int main(){
scanf("%d%d",&n,&m);
rep(i,1,n) rep(j,1,n) scanf("%lf",&a[i][j]);
rep(i,n+1,n+m) rep(j,1,n) scanf("%lf",&a[j][i]);
gauss();
}
整数版:
有O(N^3) (LCM)
O(N^3logM) (模拟GCD)
O(N^3)
(C一份~~~)
int Gauss()
{
int i,j,k;
int max_r;
int ta,tb;
int free_x_num;
int free_index;
int LCM,tmp;
int col = 0;
for(k=0; k<equ && col<var; k++,col++)
{
max_r = k;
for(i=k+1; i<equ; i++)
if(abs(a[i][col]) > abs(a[max_r][col])) max_r = i;
if(max_r != k)
for(j=k; j<var+1; j++)
swap(a[k][j],a[max_r][j]);
if(a[k][col] == 0)
{
k--;
continue;
}
for(i=k+1; i<equ; i++)
{
if(a[i][col] != 0)
{
LCM = lcm(abs(a[i][col]),abs(a[k][col]));
ta = LCM / abs(a[i][col]);
tb = LCM / abs(a[k][col]);
if(a[i][col] * a[k][col] < 0) tb = - tb;
for(j = col ; j<var+1; j++)
a[i][j] = a[i][j]*ta - a[k][j]*tb;
}
}
}
XOR方程组(没有压位):O(N^3)
压位:O(NlogMAX)
#include <cstdio>
#include <algorithm>
#define rep(i,l,r) for (int i=l;i<=r;++i)
#define per(i,r,l) for (int i=r;i>=l;--i)
const int MAX_N=40;
bool a[MAX_N][MAX_N];
int n,m;
void gauss(){
rep(i,1,n){
rep(j,i,n) if (a[j][i]>a[i][i]) rep(k,1,n+1) std::swap(a[i][k],a[j][k]);
rep(j,1,n) if (i!=j&&a[j][i]) rep(k,i,n+1) a[j][k]^=a[i][k];
}
}
int ans=100;
bool x[MAX_N];
void dfs(int v,int tot){ //自由元枚举
if (tot>ans) return;
if (v<=0){ans=tot;return;}
if (a[v][v]){
x[v]=a[v][n+1];
rep(k,v+1,n) x[v]^=a[v][k]&x[k];
dfs(v-1,tot+x[v]);
}else{
x[v]=1;dfs(v-1,tot+1);
x[v]=0;dfs(v-1,tot);
}
}
int main(){
freopen("lights.in","r",stdin);
freopen("lights.out","w",stdout);
scanf("%d%d",&n,&m);
rep(i,1,n) a[i][i]=a[i][n+1]=1;
rep(i,1,m){
int x,y;scanf("%d%d",&x,&y);
a[x][y]=a[y][x]=1;
}
gauss();
dfs(n,0);
printf("%d\n",ans);
}