题目:BZOJ2337.
题目大意:给定一张
n
n
n个点
m
m
m条边的带边权无向连通图,求从点
1
1
1到点
n
n
n的异或和的期望.
1
≤
n
≤
100
,
1
≤
m
≤
1
0
4
1\leq n\leq 100,1\leq m\leq 10^4
1≤n≤100,1≤m≤104,边权
∈
[
0
,
1
0
9
]
\in[0,10^9]
∈[0,109].
看到位运算先想到拆位,显然每一位互不影响.
假设现在考虑某一位,我们设 f [ i ] f[i] f[i]表示这一位从点 i i i出发到点 n n n异或和为 1 1 1的概率.
设
d
e
g
[
i
]
deg[i]
deg[i]表示点
i
i
i的度,容易列出方程:
f
[
x
]
=
∑
(
x
,
y
)
∈
E
1
d
e
g
[
x
]
∗
{
f
[
y
]
v
(
x
,
y
)
=
0
1
−
f
[
y
]
v
(
x
,
y
)
=
1
f[x]=\sum_{(x,y)\in E}\frac{1}{deg[x]}* \left\{\begin{matrix} f[y]&v(x,y)=0\\ 1-f[y]&v(x,y)=1 \end{matrix}\right.
f[x]=(x,y)∈E∑deg[x]1∗{f[y]1−f[y]v(x,y)=0v(x,y)=1
然后我们根据这个方程高消一下即可得到最后的概率,也就可以求得期望了.
时间复杂度 O ( n 3 log 1 0 9 ) O(n^3\log 10^9) O(n3log109).
注意自环不能加两次,只能当一条有向边算.
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define Abigail inline void
typedef long long LL;
const int N=100,M=10000,C=30;
const double eps=1e-8;
int n,m;
struct side{
int y,next,v;
}e[M*2+9];
int lin[N+9],cs;
void Ins(int x,int y,int v){e[++cs].y=y;e[cs].v=v;e[cs].next=lin[x];lin[x]=cs;}
int deg[N+9];
double ans,mat[N+9][N+9];
void Gauss(){
int now=1;
for (int i=1;i<n;++i){
int r=now;
for (int j=now+1;j<n;++j)
if (abs(mat[j][i])>abs(mat[r][i])) r=j;
if (abs(mat[r][i])<eps) continue;
if (r^now) swap(mat[r],mat[now]);
double t=mat[now][i];
for (int j=1;j<=n;++j) mat[now][j]/=t;
for (int j=1;j<n;++j)
if (j^now){
t=mat[j][i];
for (int k=1;k<=n;++k) mat[j][k]-=t*mat[now][k];
}
++now;
}
for (int i=1;i<n;++i) mat[i][n]/=mat[i][i];
}
Abigail into(){
scanf("%d%d",&n,&m);
int x,y,v;
for (int i=1;i<=m;++i){
scanf("%d%d%d",&x,&y,&v);
Ins(x,y,v);++deg[x];
if (x^y) Ins(y,x,v),++deg[y];
}
}
Abigail work(){
for (int i=0;i<=C;++i){
for (int j=1;j<n;++j)
for (int k=1;k<=n;++k)
mat[j][k]=0;
for (int j=1;j<n;++j){
mat[j][j]-=1.0;
for (int k=lin[j];k;k=e[k].next)
if (e[k].y==n) mat[j][n]-=1.0*(e[k].v>>i&1)/deg[j];
else if (e[k].v>>i&1) mat[j][e[k].y]-=1.0/deg[j],mat[j][n]-=1.0/deg[j];
else mat[j][e[k].y]+=1.0/deg[j];
}
Gauss();
ans+=mat[1][n]*(1<<i);
}
}
Abigail outo(){
printf("%.3lf\n",ans);
}
int main(){
into();
work();
outo();
return 0;
}