Luogu3211 XOR和路径

Description

link

一个有 (n) 个点,(m) 条边的无向图,边带权

求从 (1)(n) 点的路径异或和的期望

啊,等概率向下一条边走

(n le 100)

Solution

异或和的期望?又 (int)(double)

不会处理??

按位处理了解一下!!

定义 (f_i) 表示当前位中从 (i)(n) 点的异或和为 (1) 的期望

然后最后答案直接乘起来就好了

转移就还是很普通

[f_i=frac{1}{d_i}(sumlimits_{w(i,j)=1} (1-f_j)+sumlimits_{w(i,j)=0} f_j) ]

注意异或,所以是反过来的

然后推式子,高斯消元,统计答案就行了呗

Code

#include<bits/stdc++.h>
using namespace std;
#define int long long
namespace yspm{
	inline int read()
	{
		int res=0,f=1; char k;
		while(!isdigit(k=getchar())) if(k=='-') f=-1;
		while(isdigit(k)) res=res*10+k-'0',k=getchar();
		return res*f;
	}
	const int N=210;
	struct node{
		int to,dis,nxt;
	}e[N*N*2];
	int head[N],cnt;
	inline void add(int u,int v,int w)
	{
		e[++cnt].dis=w; e[cnt].nxt=head[u]; e[cnt].to=v;
		return head[u]=cnt,void();
	}
	int n,m,d[N];
	double ans,f[N],a[N][N];
	inline void guass(int x)
	{
		memset(a,0,sizeof(a)); memset(f,0,sizeof(f)); 
		for(int i=1;i<n;++i)
		{
			a[i][i]=d[i];
			for(int j=head[i];j;j=e[j].nxt)
			{
				int t=e[j].to; 
				if(e[j].dis&(1<<x)) a[i][t]+=1.0,a[i][n+1]+=1.0;
				else a[i][t]-=1.0;
			}
		}a[n][n]=1; 
		for(int i=1;i<=n;++i)
		{
			int t=i; for(int j=i+1;j<=n;++j) if(fabs(a[j][i])>fabs(a[t][i])) t=j; 
			if(t!=i) swap(a[t],a[i]); 
			for(int j=i+1;j<=n;++j)
			{
				double p=a[j][i]/a[i][i];
				for(int k=1;k<=n+1;++k) a[j][k]-=p*a[i][k];
			} 
		}
		for(int i=n;i>=1;--i)
		{
			for(int j=i+1;j<=n;++j) a[i][n+1]-=a[i][j]*f[j]; 
			f[i]=a[i][n+1]/a[i][i]; 
		}
		return ;
	}
	signed main()
	{
		n=read(); m=read();
		for(int i=1;i<=m;++i)
		{
			int x=read(),y=read(),z=read();
			add(x,y,z); d[x]++;
			if(x==y) continue; d[y]++; add(y,x,z);
		}
		for(int i=0;i<30;++i)
		{
			guass(i); 
			ans+=(1<<i)*f[1];
		} printf("%.3lf
",ans);
		return 0;
	}
}
signed main(){return yspm::main();}

Review

这种无法正常运算的运算可以考虑按位处理啥的

高斯消元一定要开 (double) 呀!!!

原文地址:https://www.cnblogs.com/yspm/p/12865058.html