zoukankan      html  css  js  c++  java
  • 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) 呀!!!

  • 相关阅读:
    身份证号码验证(转)
    《编写有效用例》读书笔记2
    《编写有效用例》读书笔记3
    1
    《实例化需求:团队如何交付正确的软件》阅读笔记3
    《实例化需求:团队如何交付正确的软件》阅读笔记2
    《实例化需求:团队如何交付正确的软件》阅读笔记1
    项目目标文档
    系统利益相关者描述
    《代码阅读方法与实践》阅读笔记3
  • 原文地址:https://www.cnblogs.com/yspm/p/12865058.html
Copyright © 2011-2022 走看看