码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj2337

时间:2018-03-04 20:02:33      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:ble   return   pen   color   splay   注意   print   wap   src   

高斯消元+概率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\n", ans);
    return 0;
}
View Code

 

bzoj2337

标签:ble   return   pen   color   splay   注意   print   wap   src   

原文地址:https://www.cnblogs.com/19992147orz/p/8505549.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!