• bzoj 2337 高斯消元+概率DP


      题目大意:

    每条路径上有一个距离值,从1走到N可以得到一个所有经过路径的异或和,求这个异或和的数学期望

    这道题直接去求数学期望的DP会导致很难列出多元方程组

    我们可以考虑每一个二进制位从1走到N的平均概率值

    因为整个图是联通的那么所有点都默认会处于多元方程组中

    Pi = p[i] * sigma( v&d[i][j]?(1-Pj):Pj)

    v是当前二进制位代表的数值

    这里需要注意的是自环的加边情况,自环只加一次边,不能向平时那样加无向边一样

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <cmath>
      6 #include <queue>
      7 using namespace std;
      8 const int N = 205;
      9 const int M = 10005;
     10 #define eps 1e-8
     11 int first[N] , k , degree[N] , n , m;
     12 double p[N] , a[N][N];
     13 
     14 void debug()
     15 {
     16     for(int i=0 ; i<n ; i++){
     17         for(int j=0 ; j<=n ; j++)
     18             cout<<a[i][j]<<" ";
     19         cout<<endl;
     20     }
     21 }
     22 
     23 struct Edge{
     24     int y , next , d;
     25     Edge(int y=0 , int next=0 , int d=0):y(y),next(next),d(d){}
     26 }e[M<<1];
     27 
     28 void add_edge(int x,int y,int d)
     29 {
     30     e[k] = Edge(y , first[x] , d);
     31     first[x] = k++;
     32 }
     33 
     34 int get_width(int x)
     35 {
     36     int ret =0 ;
     37     while(x)
     38     {
     39         x>>=1;
     40         ret++;
     41     }
     42     return ret;
     43 }
     44 
     45 void build(int v)
     46 {
     47     memset(a , 0 , sizeof(a));
     48     for(int i=0 ; i<n ; i++){
     49         a[i][i] = 1;
     50         if(i==n-1) continue;
     51         for(int j=first[i] ; ~j ; j=e[j].next){
     52             int u = e[j].y;
     53             if(v&e[j].d){
     54                 a[i][u] += p[i];
     55                 a[i][n] += p[i];
     56             }else{
     57                 a[i][u] -= p[i];
     58             }
     59         }
     60     }
     61    // debug();
     62 }
     63 
     64 int gauss(int n)
     65 {
     66     int i,j,k;
     67     for(i=0 , j=0 ; i<n&&j<n ; j++){
     68         for(k=i ; k<n ; k++)
     69             if(fabs(a[k][j])>eps) break;
     70         if(k<n){
     71             if(i!=k)
     72                 for(int r=j ; r<=n ; r++) swap(a[i][r],a[k][r]);
     73             double tt = 1.0/a[i][j];
     74             for(int r=j ; r<=n ; r++) a[i][r] *= tt;
     75             for(int r=0 ; r<n ; r++){
     76                 if(r == i) continue;
     77                 for(int t=n ; t>=j ; t--)
     78                     a[r][t] -= a[i][t]*a[r][j];
     79             }
     80             i++;
     81         }
     82     }
     83     for(int r=i ; r<n ; r++)
     84         if(fabs(a[r][n])>eps) return 0;
     85     return 1;
     86 }
     87 
     88 int main()
     89 {
     90     #ifndef ONLINE_JUDGE
     91         freopen("a.in" , "r" , stdin);
     92     #endif // ONLINE_JUDGE
     93     while(~scanf("%d%d" , &n , &m))
     94     {
     95         memset(first , -1 , sizeof(first));
     96         memset(degree , 0 , sizeof(degree));
     97         k = 0;
     98         int maxn = 0;
     99         for(int i=0 ; i<m ; i++){
    100             int x,y,d;
    101             scanf("%d%d%d" , &x , &y , &d);
    102             add_edge(x-1,y-1,d);
    103             if(x!=y){
    104                 add_edge(y-1 , x-1 , d);
    105                 degree[x-1]++ , degree[y-1]++;
    106             }
    107             else degree[x-1]++;
    108             maxn = max(maxn , d);
    109         }
    110         for(int i=0 ; i<n ; i++) p[i] = 1.0/(degree[i]*1.0);//得到从当前点每条边出发的概率
    111         int len = get_width(maxn);
    112         double ret= 0;
    113         for(int i=0 ; i<len ; i++){
    114             int v = 1<<i;
    115             build(v);
    116             gauss(n);
    117             ret += v*a[0][n];
    118         }
    119         printf("%.3f
    " , ret);
    120     }
    121     return 0;
    122 }
  • 相关阅读:
    sklearn.neighbors.KNeighborsClassifier的k-近邻算法使用介绍
    修改或定义sudo下的PATH环境变量
    Linux安装deb后缀包
    Linux截图软件shutter安装
    Python变量前'*'和'**'的作用
    线段树入门
    机器学习实战源码&数据集
    Spring Boot 自动配置原理(精髓)
    Spring Boot 注解配置 day03
    Spring Boot 配置_yaml语法介绍 day02
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4535619.html
Copyright © 2020-2023  润新知