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 }