• 【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
    
    */
    
  • 相关阅读:
    Android Virtual Device(AVD)屏幕大小调整
    修改obj三维模型文件中坐标z为其相反数
    AE安装检测(C++)
    单件模式
    地形转立体实验截图
    保持几何特征的三维建筑物模型简化方法 毕业硕士论文
    判断多边形点串存放序列
    mathematica 查找 mathpass 注册文件位置
    在线调色板搜集
    图标资源搜集
  • 原文地址:https://www.cnblogs.com/ftotl/p/11856686.html
Copyright © 2020-2023  润新知