bzoj2337 [HNOI2011]XOR和路径

Description

正解:高斯消元。

我们考虑把每个二进制位分开考虑。设x[i]为i到n路径异或和为1的概率,则我们要根据边分情况讨论。这个方程和游走那题方程有点类似。x[i]=Σx[j]/d[i]+Σ(1-x[k])/d[i]。其中,i与j连0的边,i与k连1的边。那么我们列出方程以后,用高斯消元求解,最后求出Σx[1]*(1<<k),k为当前二进制位,这个就是答案了。

 

 1 //It is made by wfj_2048~
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <cstring>
 5 #include <cstdlib>
 6 #include <cstdio>
 7 #include <vector>
 8 #include <cmath>
 9 #include <queue>
10 #include <stack>
11 #include <map>
12 #include <set>
13 #define inf (1e18)
14 #define eps (1e-9)
15 #define il inline
16 #define RG register
17 #define ll long long
18 #define double long double
19 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
20 
21 using namespace std;
22 
23 struct edge{ int nt,to,dis; }g[20010];
24 
25 int head[110],d[110],n,m,num;
26 double a[110][110],ans;
27 
28 il int gi(){
29     RG int x=0,q=1; RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
30     if (ch=='-') q=-1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x;
31 }
32 
33 il void insert(RG int from,RG int to,RG int dis){ g[++num]=(edge){head[from],to,dis},head[from]=num; return; }
34 
35 il void gauss(){
36     for (RG int i=1;i<=n;++i){
37     RG double maxs=-1.0; RG int id=i;
38     for (RG int j=i;j<=n;++j) if (fabs(a[j][i])+eps>maxs) maxs=fabs(a[j][i]),id=j;
39     if (id!=i) for (RG int j=1;j<=n+1;++j) swap(a[i][j],a[id][j]);
40     RG double t=a[i][i]; for (RG int j=i;j<=n+1;++j) a[i][j]/=t;
41     for (RG int j=1;j<=n;++j){
42         if (i==j) continue; t=a[j][i];
43         for (RG int k=1;k<=n+1;++k) a[j][k]-=t*a[i][k];
44     }
45     }
46     return;
47 }
48 
49 il void work(){
50     n=gi(),m=gi();
51     for (RG int i=1,u,v,w;i<=m;++i){
52     u=gi(),v=gi(),w=gi(),d[u]++,insert(u,v,w);
53     if (u!=v) d[v]++,insert(v,u,w);
54     }
55     for (RG int k=0;k<=30;++k){
56     memset(a,0,sizeof(a));
57     for (RG int x=1;x<n;++x){
58         a[x][x]=1.0;
59         for (RG int i=head[x];i;i=g[i].nt)
60         if (g[i].dis&(1<<k)) a[x][g[i].to]+=1.0/d[x],a[x][n+1]+=1.0/d[x];
61         else a[x][g[i].to]-=1.0/d[x];
62     }
63     a[n][n]=1.0; gauss(); ans+=a[1][n+1]*(1<<k);
64     }
65     printf("%0.3Lf",ans); return;
66 }
67 
68 int main(){
69     File("xor");
70     work();
71     return 0;
72 }

 

posted @ 2017-03-11 14:21  wfj_2048  阅读(517)  评论(0编辑  收藏  举报