zoukankan      html  css  js  c++  java
  • 【bzoj2337】[HNOI2011]XOR和路径 期望dp+高斯消元

    题目描述


    题解

    期望dp+高斯消元

    直接求总体的期望异或和比较困难,我们可以考虑按位拆分一下,这样每一位就只有0/1两种选择。

    设f[i]表示从i到n的期望异或和,那么$f[y]=sumlimits_{exist x1 o y=0}frac{f[x1]}{d[x1]}+sumlimits_{exist x2 o y=1}frac{1-f[x2]}{d[x2]}$,其中x1->y=0表示x1到y有权值为0的边,x2->y=1表示x2到y有权值为1的边。

    这里和 bzoj3143 的处理类似,同样需要特殊处理n,令f[n]=0。

    不过这道题最恶心之处在于它有重边和自环,对于重边需要把"="变为"+=",对于自环,按照样例的意思应该是把自环边的度数看作1而不是2处理(两种方式走自环算一种)

    然后使用高斯消元求解,将f[1]乘上拆分的位加到答案中。

    时间复杂度$O(n^3log n)$

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #define N 110
    #define M 20010
    using namespace std;
    int n , m , head[N] , to[M] , len[M] , next[M] , cnt , d[N] , x[M] , y[M] , z[M];
    double a[N][N];
    double cal(int t)
    {
    	int i , j , k;
    	double f;
    	memset(a , 0 , sizeof(a));
    	for(i = 1 ; i <= m ; i ++ )
    	{
    		if(z[i] & t)
    		{
    			a[x[i]][y[i]] += 1 , a[x[i]][n + 1] += 1;
    			if(x[i] != y[i]) a[y[i]][x[i]] += 1 , a[y[i]][n + 1] += 1;
    		}
    		else
    		{
    			a[x[i]][y[i]] -= 1;
    			if(x[i] != y[i]) a[y[i]][x[i]] -= 1;
    		}
    	}
    	for(i = 1 ; i <= n + 1 ; i ++ ) a[n][i] = 0;
    	for(i = 1 ; i <= n ; i ++ ) a[i][i] += d[i];
    	for(i = 1 ; i <= n ; i ++ )
    	{
    		for(k = i , j = i + 1 ; j <= n ; j ++ )
    			if(fabs(a[j][i]) > fabs(a[k][i]))
    				k = j;
    		for(j = i ; j <= n + 1 ; j ++ ) swap(a[k][j] , a[i][j]);
    		for(j = i + 1 ; j <= n ; j ++ )
    			for(f = a[j][i] / a[i][i] , k = i ; k <= n + 1 ; k ++ )
    				a[j][k] -= a[i][k] * f;
    	}
    	for(i = n ; i  ; i -- )
    	{
    		for(j = i + 1 ; j <= n ; j ++ ) a[i][n + 1] -= a[i][j] * a[j][n + 1];
    		a[i][n + 1] /= a[i][i];
    	}
    	return a[1][n + 1];
    }
    int main()
    {
    	int i;
    	double ans = 0;
    	scanf("%d%d" , &n , &m);
    	for(i = 1 ; i <= m ; i ++ )
    	{
    		scanf("%d%d%d" , &x[i] , &y[i] , &z[i]) , d[x[i]] ++ ;
    		if(x[i] != y[i]) d[y[i]] ++ ;
    	}
    	for(i = 1 << 30 ; i ; i >>= 1) ans += cal(i) * i;
    	printf("%.3lf
    " , ans);
    	return 0;
    }
    
  • 相关阅读:
    LeetCode 1122. Relative Sort Array (数组的相对排序)
    LeetCode 46. Permutations (全排列)
    LeetCode 47. Permutations II (全排列 II)
    LeetCode 77. Combinations (组合)
    LeetCode 1005. Maximize Sum Of Array After K Negations (K 次取反后最大化的数组和)
    LeetCode 922. Sort Array By Parity II (按奇偶排序数组 II)
    LeetCode 1219. Path with Maximum Gold (黄金矿工)
    LeetCode 1029. Two City Scheduling (两地调度)
    LeetCode 392. Is Subsequence (判断子序列)
    写程序判断系统是大端序还是小端序
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/7056128.html
Copyright © 2011-2022 走看看