高斯消元+期望dp
这种题套路还是明显吧
利用点的期望推边的。首先这个得按位算:我TM看见XOR还以为是线性基呢。
对于每一位对于每个点f[]表示到达1的期望
f[n]=0;
f[i]=sigma(son[x]->w&(1<<bit)?1/cd[x]:0)
高斯消元就好了
#include<bits/stdc++.h>
using namespace std;
const int N=4e5+10;
const double eps=1e-16;
struct Front_star{
int u,v,w,nxt;
}e[N*4];
int cnt=1;
int first[N]={0};
void add(int u,int v,int w){
cnt++;
e[cnt].u=u;
e[cnt].v=v;
e[cnt].w=w;
e[cnt].nxt=first[u];
first[u]=cnt;
}
double a[201][201]={};
int n,m;
int cd[N]={0};
void gauss(){
for(int i=1;i<=n;i++){
int id=i;
double maxsum=-1.0;
for(int j=i;j<=n;j++){
if(fabs(a[j][i])+eps>maxsum){
id=j,maxsum=fabs(a[j][i]);
}
}
if(id!=i){
for(int j=1;j<=n+1;j++){
swap(a[i][j],a[id][j]);
}
}
double t=a[i][i];
for(int j=1;j<=n+1;j++){
a[i][j]/=t;
}
for(int j=1;j<=n;j++){
if(j!=i){
double t=a[j][i];
for(int k=1;k<=n+1;k++){
a[j][k]-=t*a[i][k];
}
}
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
if(u!=v){
add(u,v,w);
add(v,u,w);
cd[u]++;
cd[v]++;
}
else add(u,v,w),cd[u]++;
}
double ans=0;
for(int i=0;i<=30;i++){//bit
memset(a,0,sizeof(a));
for(int x=1;x<n;x++){
a[x][x]=1.0;
for(int j=first[x];j;j=e[j].nxt){
int v=e[j].v;
if(e[j].w&(1<<i)){
a[x][v]+=1.0/cd[x];
a[x][n+1]+=1.0/cd[x];
}
else a[x][v]-=(1.0/cd[x]);
}
}
a[n][n]=1.0;
gauss();
ans+=(a[1][n+1])*(1<<i);
}
cout<<fixed<<setprecision(3)<<ans;
}