• bzoj2337


    高斯消元+概率dp

    我好纸张

    设dp[i]表示i到n异或和为1的概率,那么暴力高斯消元就行了,注意方程中n那一行要清零

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    const int N = 105;
    struct edge {
        int u, v, w;
    } e[N * N];
    int n, m;
    double ans;
    double deg[N], a[N][N];
    void gauss_jordan() {
        for(int i = 1; i <= n; ++i) {
            int p = i;
            for(int j = i; j <= n; ++j) {
                if(fabs(a[j][i]) > fabs(a[p][i])) {
                    p = j;
                }
            }
            for(int j = 1; j <= n + 1; ++j) {
                swap(a[i][j], a[p][j]);
            }
            double d = a[i][i];
            for(int j = 1; j <= n + 1; ++j) {
                a[i][j] /= d;
            }
            for(int j = 1; j <= n; ++j) {
                if(i != j) {
                    double d = a[j][i];
                    for(int k = 1; k <= n + 1; ++k) {
                        a[j][k] -= a[i][k] * d;
                    }
                }
            }
        }
    }
    void solve(int bit) {
        for(int i = 1; i <= n; ++i) {
            for(int j = 1; j <= n + 1; ++j) {
                a[i][j] = 0;
            }
        }
        for(int i = 1; i <= n; ++i) {
            a[i][i] = -1;
        }
        for(int i = 1; i <= m; ++i) {
            int t = e[i].w >> bit & 1, u = e[i].u, v = e[i].v;
            if(t) {
                a[u][v] -= 1.0 / deg[u];
                if(u != v) {
                    a[v][u] -= 1.0 / deg[v];
                }
                a[u][n + 1] -= 1.0 / deg[u];
                if(u != v) {
                    a[v][n + 1] -= 1.0 / deg[v];
                }
            } else {
                a[u][v] += 1.0 / deg[u];
                if(u != v) {
                    a[v][u] += 1.0 / deg[v];
                }
            }
        }
        for(int i = 1; i <= n + 1; ++i) {
            a[n][i] = 0;
        }
        a[n][n] = -1;
        gauss_jordan();
        ans += a[1][n + 1] * (1 << bit);
    }
    int main() {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= m; ++i) {
            scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w);
            deg[e[i].u] += 1.0;
            if(e[i].u != e[i].v) {
                deg[e[i].v] += 1.0;
            }
        }
        for(int bit = 0; bit < 30; ++bit) {
            solve(bit);
        }
        printf("%.3f
    ", ans);
        return 0;
    }
    View Code
  • 相关阅读:
    Java-MyBatis:MyBatis 3 入门
    Java-MyBatis-3.0:MyBatis 3 简介
    DB-MySQL:MySQL 教程
    DB-MySQL:MySQL GROUP BY
    DB-MySQL:MySQL 连接的使用
    人行
    PHP 面试题数组篇[ 整理中 ]
    java中Condition类的详细介绍(详解)
    java中Condition类的详细介绍(详解)
    java中Condition类的详细介绍(详解)
  • 原文地址:https://www.cnblogs.com/19992147orz/p/8505549.html
Copyright © 2020-2023  润新知