毕竟是本人的第一次写高斯消元,所以你会发现代码与题解神似,至于为什么,无可奉告
其实思想蛮简单,主要来谈谈代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#define maxn 305
#define esp (1e-14)
using namespace std;
int n,m,f[maxn];
long double a[maxn][maxn];//构造的高斯消元的矩阵,代表第i个方程式的第j个系数是多少 ,精度要求很高
void read(int& x){
x=0;
char c=getchar();
for(;c<'0'||c>'9';c=getchar());
for(;c>='0' && c <= '9'; c = getchar() ){
x = x*10 + c - '0';
}
}
int main(){
read( n );read(m);//读入优化
int x,y;
for(int i=1;i <= m ; i++){
read(x);read(y);
f [ x ] = y;//如果有传送的话,到哪里
}
for(int i = 1 ; i < n ; i++ ){
a[ i ][ i ]=6;//第一个方程
if( f[ i ] )a[ i ][ f[ i ] ]=-6.0;//如果有传送门 系数直接抵消 x-y=0 相当于 x=y
else{
a[i][n+1]=6.0;//方程右边的常数
for(int j = 1 ;j <= 6; j++){
if(i+j>n)a[i][i]-=1.0;//另外一个方程
else a[i][i+j]-=1.0;
}
}
}
a[n][n]=1.0;//最后的方程
a[n][n+1]=0;
//高斯消元
for(int i=1;i<=n;i++){
int p=i;
for(int j=i+1;j<=n;j++){//向下查找第j个系数不为0的方程
if(fabs(a[j][i])> esp)p=j;
}
if(fabs(a[p][i])>esp){
for(int j=i;j<=n+1;j++)swap(a[i][j],a[p][j]);//把方程移上来
for(int j=i+1;j<=n;j++){//向下消元 同时除去其他的系数
if(fabs(a[j][i])>esp){
long double k=a[j][i]/a[i][i];//消元
for(int t=i;t<=n+1;t++)a[j][t]-=a[i][t]*k;//系数相减
}
}
}
}
//回带 a[i][n+1]就是第i个未知数的解
for(int i=n;i>=1;i--){
for(int j = i+1;j <= n; j++)if(fabs(a[i][j])>esp){
a[i][n+1]-=a[j][n+1]*a[i][j];//用已知的解求未知解
}
if(abs(a[i][i])<=esp&&abs(a[i][n+1])>esp){//如果出现矛盾
printf("-1");
return 0;
}
a[i][1+n]/=a[i][i];//求出当前的解
}
printf("%.12lf",(double)a[1][1+n]);//输出第一个未知数的解 就是答案
return 0;
}