zoukankan      html  css  js  c++  java
  • HNOI2011 XOR和路径

    题目链接:戳我

    对于异或,有一个套路是要把每一位拆开算贡献,这个题就是这样子的。

    对于当前位,我们设(dp[i])表示从i到n的路径上该位为1的概率。
    (为什么不设(dp[i])表示从1到i的路径上的概率呢,因为有可能当前点到达不了n)

    [dp[u]=sum_{w(u,v)=1}frac{1-dp[v]}{du[u]}+sum_{w(u,v)=0}frac{dp[v]}{du[u]} ]

    然后因为这个不能线性递推,所以我们设未知数,用高斯消元解方程就行了。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define MAXN 101
    using namespace std;
    int n,m,t;
    int du[MAXN+10],head[MAXN+10];
    double ans;
    double f[MAXN+10][MAXN+10],sum[MAXN+10];
    struct Edge{int nxt,to,dis;}edge[200010];
    inline void add(int from,int to,int dis){edge[++t].nxt=head[from],edge[t].to=to,edge[t].dis=dis,head[from]=t;}
    inline void init(int pos)
    {
        memset(f,0,sizeof(f));
        for(int i=1;i<=n;i++) f[i][i]=1.0;
        for(int i=1;i<n;i++)
            for(int j=head[i];j;j=edge[j].nxt)
            {
                int v=edge[j].to;
                if(edge[j].dis&(1<<pos)) f[i][v]+=1.0/du[i],f[i][n+1]+=1.0/du[i];
                else f[i][v]-=1.0/du[i];
            }
    }
    inline void guass()
    {
        for(int i=1;i<=n;i++)
        {
            int pos=i;
            for(int j=i+1;j<=n;j++)
                if(fabs(f[j][i])>fabs(f[pos][i]))
                    pos=j;
            if(pos!=i) swap(f[pos],f[i]);
            double cur=f[i][i];
            for(int j=i+1;j<=n+1;j++) f[i][j]/=cur;
            for(int j=i+1;j<=n;j++)
            {
                cur=f[j][i];
                for(int k=i+1;k<=n+1;k++)
                    f[j][k]-=f[i][k]*cur;
            }
        }       
        sum[n]=f[n][n+1];
        for(int i=n-1;i>=1;i--)
        {
            sum[i]=f[i][n+1];
            for(int j=i+1;j<=n;j++) sum[i]-=f[i][j]*sum[j];
        }
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin);
        #endif
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w),du[u]++;
            if(u!=v) add(v,u,w),du[v]++;
        }
        for(int i=0;i<=31;i++)
        {
            init(i);
            guass();
            ans+=1.0*(1ll<<i)*sum[1];
        }
        printf("%.3lf
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    vue项目发布到服务器之后出现空白页和图片找不到的问题
    H5中设置一个元素一直在页面的最底部
    vue项目打包出现的问题(日常记录)
    vue写H5注册页面
    vue项目中动态图片生成
    Java中boolean类型占用多少个字节
    Java将一个目录下的所有数据复制到另一个目录下
    Java使用递归找出某目录下的所有子目录以及子文件
    实现短信验证码
    C#连接Oracle数据库(直接引用dll使用)
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10874962.html
Copyright © 2011-2022 走看看