# 浅谈期望的线性性（可加性）【CodeForces280c】【bzoj3036】【bzoj3143】

[pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=63399955

（感性理解一下）
E(X+Y)=E(X)+E(Y)

## Codeforces280c

N<=100000

dfs就可以了

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int N=100000+5;

int n;
double ans=0;

void dfs(int u,int f,int dep){
ans+=1.0/dep;
int v=end[i];
if(v==f) continue;
dfs(v,u,dep+1);
}
}
hh++;
end[hh]=b;
}
int main(){
scanf("%d",&n);
for(int i=1;i<n;i++){
int a,b;
scanf("%d%d",&a,&b);
}
dfs(1,1,1);
printf("%.20lf",ans);
return 0;
}

## bzoj3036绿豆蛙的归宿

Description

Input

Output

Sample Input
4 4
1 2 1
1 3 2
2 3 3
3 4 4
Sample Output
7.00
HINT

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;

const int N=100000+5;

int n,m,in[N],out[N];
queue<int> q;
double p[N],ans=0;

hh++;
end[hh]=b;
len[hh]=c;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
in[b]++,out[a]++;
}
q.push(1);
p[1]=1;
while(!q.empty()){
int u=q.front();q.pop();
int v=end[i];
ans+=p[u]/out[u]*len[i];
p[v]+=p[u]/out[u];
in[v]--;
if(in[v]==0){
q.push(v);
}
}
}
printf("%.2lf",ans);
return 0;
}

## bzoj3143[Hnoi2013]游走

Description

Input

Output

Sample Input
3 3
2 3
1 2
1 3
Sample Output
3.333

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int N=500+5;
const double eps=1e-10;

int n,m;
int deg[N],edge[N*N][2];
double g[N][N],p[N],ep[N*N];

hh++;
end[hh]=b;
}
void solve(){
int cnt=0;
for(int k=1;k<n;k++){
int j=-1;
for(int i=cnt+1;i<n;i++){
if(fabs(g[i][k])>eps){
j=i;
break;
}
}
if(j==-1) continue;
cnt++;
for(int i=1;i<=n;i++) swap(g[cnt][i],g[j][i]);
for(int i=1;i<n;i++){
if(i==cnt) continue;
if(fabs(g[i][k])<eps) continue;
double tmp=g[i][k]/g[cnt][k];
for(j=1;j<=n;j++)
g[i][j]-=g[cnt][j]*tmp;
}
}
for(int i=1;i<n;i++){
p[i]=g[i][n]/g[i][i];
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int a,b;
scanf("%d%d",&a,&b);
deg[a]++,deg[b]++;
edge[i][0]=a,edge[i][1]=b;
}
int v=end[i];
if(v==n) continue;
g[1][v]=1.0/deg[v];
}
g[1][1]=-1;
g[1][n]=-1;
for(int k=2;k<n;k++){
g[k][k]=-1;
int v=end[i];
if(v==n) continue;
g[k][v]=1.0/deg[v];
}
}
solve();
for(int i=1;i<=m;i++){
int a=edge[i][0],b=edge[i][1];
ep[i]=p[a]/deg[a]+p[b]/deg[b];
}
sort(ep+1,ep+m+1);
double ans=0;
for(int i=1;i<=m;i++){
ans+=ep[i]*(m-i+1);
}
printf("%.3lf",ans);
return 0;
}

1、分解成小的、可计算的期望问题，来解决大的、不可计算的期望问题
2、无后效性的可直接递推。有后效性的可解方程。

posted @ 2017-10-31 19:09  LinnBlanc  阅读(2563)  评论(0编辑  收藏  举报