zoukankan      html  css  js  c++  java
  • 【BZOJ2337】XOR和路径(高斯消元)

    题目链接

    大意

    给出(N)个点,(M)条边的一张图,其中每条边都有一个非负整数边权。
    一个人从1号点出发,在与该点相连的边中等概率的选择一条游走,直到走到(N)号点。
    问:将这条路径上的边权异或起来的期望值为多少。
    (图中可能有重边与自环)

    思路

    对于异或,我们考虑逐位解决,这样之后,边权只有0/1。

    我们设(Dp[u])表示从(u)(N)路径的期望异或值为1时的概率。
    那么对于除了(N)号点的每个点,我们将它相连的按边权边分为两类。

    我们设边权为0的边相连的点为(v0),边权为1的边相连的点为(v1)
    那么我们应该有(Dp[u]=sum frac{Dp[v1]}{size}+sum frac{1-Dp[v2]}{size})

    化一下简得到:(Dp[u]-sum frac{Dp[v1]}{size}+sum frac{Dp[v2]}{size}=frac{siz[v2]}{size})

    (Dp[u]cdot size-sum{Dp[v1]}+sum{Dp[v2]}=siz[v2])

    这样的方程共有(N-1)个(除开(N)号点)。
    而左边共有为((N-1))个未知数((Dp[N]=0))。
    特殊的,对于(N)号点,我们需要特殊开一个方程:(Dp[N]=0).
    这样,我们就可以用高斯消元来解决了。

    而最终所求就是各个位时的相关贡献,总复杂度为(O(N^3logV))

    代码

    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define LD long double
    const int MAXN=105;
    int N,M;
    LD Ans0;
    LD Ans[MAXN];
    LD A[MAXN][MAXN];
    vector<int>P[MAXN],T[MAXN];
    LD Abs(LD X){return X<0?-X:X;}
    void GX(){
    	for(int j=1;j<=N;j++){
    		int Mx=j;
    		for(int i=j+1;i<=N;i++)
    			if(Abs(A[i][j])>Abs(A[Mx][j]))
    				Mx=i;
    		swap(A[Mx],A[j]);
    		for(int i=1;i<=N;i++){
    			if(i==j)continue;
    			LD tmp=A[i][j]/A[j][j];
    			A[i][j]=0;
    			for(int k=j+1;k<=N+1;k++)
    				A[i][k]-=A[j][k]*tmp;
    		}
    	}
    	for(int i=1;i<=N;i++)
    		Ans[i]=A[i][N+1]/A[i][i];
    }
    int main(){
    	scanf("%d%d",&N,&M);
    	for(int i=1,x,y,z;i<=M;i++){
    		scanf("%d%d%d",&x,&y,&z);
    		P[x].push_back(y);
    		T[x].push_back(z);
    		if(x==y)continue;//自环.
    		P[y].push_back(x);
    		T[y].push_back(z);
    	}
    	for(int k=0;k<=30;k++){
    		for(int i=1;i<N;i++){
    			int size=P[i].size();
    			for(int j=0;j<size;j++){
    				int v=P[i][j];
    				int val=(T[i][j]&(1<<k));
    				if(val)A[i][v]+=1,A[i][N+1]+=1;
    				else A[i][v]-=1;
    			}
    			A[i][i]+=size;
    		}
    		A[N][N]=1.0;GX();
    		Ans0+=(1<<k)*Ans[1];
    		memset(A,0,sizeof(A));
    	}
    	printf("%.3Lf
    ",Ans0);
    }
    /*
    2 2
    1 1 2
    1 2 3
    
    */
    
  • 相关阅读:
    【已解决】github中git push origin master出错:error: failed to push some refs to
    好记心不如烂笔头,ssh登录 The authenticity of host 192.168.0.xxx can't be established. 的问题
    THINKPHP 5.0目录结构
    thinkphp5.0入口文件
    thinkphp5.0 生命周期
    thinkphp5.0 架构
    Django template
    Django queryset
    Django model
    Python unittest
  • 原文地址:https://www.cnblogs.com/ftotl/p/11856686.html
Copyright © 2011-2022 走看看