zoukankan      html  css  js  c++  java
  • 高斯消元的学习 + 辗转相除法

    高斯消元的学习 + 辗转相除法

    参考网站1 https://oi-wiki.org/math/gauss/

    参考网站2 https://www.cnblogs.com/xcg123/p/10679600.html

    模板 https://www.cnblogs.com/zcysky/p/6946919.html

    模板 题目:C - Museum

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1000;
    const double eps=1e-8;
    double a[maxn][maxn],del,ans[maxn];
    bool gauss(int n) {
        for (int i = 1; i <= n; i++) {
            int k = i;
            for (int j = i + 1; j <= n; j++) if (fabs(a[j][i]) > fabs(a[k][i]))k = j;
            if (fabs(del = a[k][i]) < eps)return 0;
            for (int j = i; j <= n + 1; j++) swap(a[i][j], a[k][j]);
            for (int j = i; j <= n + 1; j++) a[i][j] /= del;
            for (k = 1; k <= n; k++)
                if (k != i) {
                    del = a[k][i];
                    for (int j = i; j <= n + 1; j++)a[k][j] -= a[i][j] * del;
                }
        }
        for(int i=n;i>=1;i--) {
            double sum = a[i][n+1];
            for(int j=i+1; j<=n;j++) {
                sum -= a[i][j]*ans[j];
            }
            ans[i] = sum;
        }
        return 1;
    }
    int w[maxn][maxn];
    double p[maxn],dp[maxn][maxn],num[maxn];
    int main(){
        int n,m,sx,sy;
        scanf("%d%d%d%d",&n,&m,&sx,&sy);
        for(int i=1;i<=m;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            w[u][v]=1,w[v][u]=1;
            num[u]++,num[v]++;
        }
        for(int i=1;i<=n;i++) scanf("%lf",&p[i]),w[i][i]=1;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                for(int x=1;x<=n;x++){
                    for(int y=1;y<=n+1;y++){
                        int gx = (i-1)*n+j,gy = (x-1)*n+y;
                        if(gy==n*n+1){
    //                        printf("a[%d][%d]=%f i=%d j=%d
    ",gx,gy,a[gx][gy],i,j);
                            if(i==sx&&j==sy) a[gx][gy]=-1;
                            else a[gx][gy]=0;
                            continue;
                        }
                        if(x==i&&y==j){
                            if(x==y) a[gx][gy]=-1;
                            else a[gx][gy]=p[x]*p[y]-1;
                        }
                        else{
                            if(x!=y&&w[x][i]&&w[y][j]) {
                               if(x==i) a[gx][gy]=p[x]*(1-p[y])/num[y];
                               else if(y==j) a[gx][gy]=(1-p[x])*p[y]/num[x];
                               else a[gx][gy]=(1-p[x])*(1-p[y])/(num[x]*num[y]);
                            }
                            else a[gx][gy]=0;
                        }
    //                    printf("a[%d][%d]=%f
    ",gx,gy,a[gx][gy]);
                    }
                }
            }
        }
        gauss(n*n);
        for(int i=1;i<=n;i++){
            int x = (i-1)*n+i;
            printf("%.6f ",ans[x]);
        }
        printf("
    ");
        return 0;
    }
    

    辗转相除法

    https://www.cnblogs.com/zyb993963526/p/7360536.html

    https://www.cnblogs.com/yangsongyi/p/10697176.html

    ll K[maxn][maxn];
    ll Gauss(int n){//求矩阵K的n-1阶顺序主子式
        ll res=1;
        for(int i=1;i<=n-1;i++){//枚举主对角线上第i个元素
            for(int j=i+1;j<=n-1;j++){//枚举剩下的行
                while(K[j][i]){//辗转相除
                    ll t=K[i][i]/K[j][i];
                    for(int k=i;k<=n-1;k++)//转为倒三角
                        K[i][k]=(K[i][k]-t*K[j][k]+mod)%mod;
                    swap(K[i],K[j]);//交换i、j两行
                    res=-res;//取负
                }
            }
            res=(res*K[i][i])%mod;
        }
        return (res+mod)%mod;
    }
    
  • 相关阅读:
    关于++i和i++的左值、右值问题
    运算符优先级
    计算机中的数及其编码
    递归函数
    PHP读取excel(4)
    替换元素节点replaceChild()
    子结点childNodes
    插入节点insertBefore()
    创建节点createElement
    插入节点appendChild()
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/13451765.html
Copyright © 2011-2022 走看看