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

    和期望有关的题一脸懵逼QAQ
    题目要求的是异或和的期望,所以就把二进制的每一位都搞一遍,最后答案就是每一位的期望和。
    然后对于每一位,推出一个很鬼畜的DP方程:f[i]表示i这个点到n的概率。

    f[n][n]=1;然后枚举i,枚举i连的每个点,如果这条路的边权为1(这里指的是二进制)f[i]+=(1-f[j])/in[i]
    否则
    f[i]+=f[j]/in[i],in[i]表示的是每个点连接的边的数量。
    这里需要注意,自环的边只能加一条,in也只能+1

     这看起来像一个动态规划,但是这是一个无向图,DP好像跑不了,那怎么办?

    对于每一个i,都会有一个线性方程:
    f[i]=f[j1]/in[i]+(1-f[j2])/in[i]+......
    然后就会发现有n个方程,然后就可以用高斯消元了......简直妙不可言。
     
     1 #include<set>
     2 #include<map>
     3 #include<queue>
     4 #include<stack>
     5 #include<ctime>
     6 #include<cmath>
     7 #include<string>
     8 #include<vector>
     9 #include<cstdio>
    10 #include<cstdlib>
    11 #include<cstring>
    12 #include<iostream>
    13 #include<algorithm>
    14 using namespace std;
    15 struct data{
    16   int nex,to,w;
    17 }e[20010];
    18 int n,head[110],edge=0;
    19 double a[110][110],in[110];
    20 void add(int from,int to,int w){
    21   e[++edge].nex=head[from];
    22   e[edge].to=to;
    23   e[edge].w=w;
    24   head[from]=edge;
    25 }
    26 void gauss(){
    27   for(int i=1;i<=n;i++){
    28     int t=i;
    29     while(!a[t][i] && t<=n) t++;
    30     if(t>n) continue;
    31     for(int j=1;j<=n+1;j++) swap(a[t][j],a[i][j]);
    32     double k=a[i][i];
    33     for(int j=i;j<=n+1;j++) a[i][j]/=k;
    34     for(int j=1;j<=n;j++)
    35       if(j!=i && a[j][i]){
    36     k=a[j][i];
    37     for(int p=i;p<=n+1;p++)
    38       a[j][p]-=k*a[i][p];
    39       }
    40   }
    41 }
    42 int main()
    43 {
    44   freopen("!.in","r",stdin);
    45   freopen("!.out","w",stdout);
    46   int m,x,y,z;
    47   double ans=0.0;
    48   scanf("%d%d",&n,&m);
    49   for(int i=1;i<=m;i++){
    50     scanf("%d%d%d",&x,&y,&z);
    51     if(x!=y) add(x,y,z),add(y,x,z),in[x]++,in[y]++;
    52     else add(x,y,z),in[x]++;
    53   }
    54   for(int p=0;p<=30;p++){
    55     memset(a,0,sizeof(a));
    56     for(int i=1;i<n;i++){
    57       a[i][i]=1.0;
    58       for(int j=head[i];j;j=e[j].nex)
    59     if(e[j].w&(1<<p)) a[i][e[j].to]+=1.0/in[i],a[i][n+1]+=1.0/in[i];
    60     else a[i][e[j].to]-=1.0/in[i];
    61     }
    62     a[n][n]=1.0;
    63     gauss();
    64     ans+=a[1][n+1]*1.0*(1<<p);
    65   }
    66   printf("%.3lf",ans);
    67   return 0;
    68 }
  • 相关阅读:
    FPM
    Docker记录
    阿里云ECS发送企业邮件
    git操作
    vscode+vagrant+xdebug调试
    Spring Security开发安全的REST服务
    559. Maximum Depth of N-ary Tree
    《算法图解》之散列表
    766. Toeplitz Matrix
    893. Groups of Special-Equivalent Strings
  • 原文地址:https://www.cnblogs.com/pantakill/p/6659403.html
Copyright © 2011-2022 走看看