首页 > 代码库 > 【HNOI2011】XOR和路径

【HNOI2011】XOR和路径

技术分享

 

 

<style>pre.cjk { font-family: "Droid Sans Fallback", monospace } p { margin-bottom: 0.25cm; line-height: 120% } a:link { }</style>
和期望有关的题一脸懵逼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
 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 }

 


这看起来像一个动态规划,但是这是一个无向图,DP好像跑不了,那怎么办?
对于每一个i,都会有一个线性方程:
f[i]=f[j1]/in[i]+(1-f[j2])/in[i]+......
然后就会发现有n个方程,然后就可以用高斯消元了......简直妙不可言。

【HNOI2011】XOR和路径