[数学期望]BZOJ 1415

2 篇文章 0 订阅

Description
这里写图片描述
题解
既然是平均情况,显然就是求数学期望。我们会发现,每一个时刻猫鼠之间的最短路径一定是减小了,所以不会出现转圈的情况,所以可以用记忆化搜索,用 f[x][y] 表示猫在节点x,鼠在节点y,猫鼠相遇的期望值。题目中最终要的就是要知道猫的下一步会走到哪里,可以枚举每个点,然后BFS刷最短路,最后枚举一下, O(N2) 的复杂度就可以构造出来。所以转移方程:

f[x][y]=1+DP(nxt,son[j])degree[y]+1
其中nxt表示猫下一步走到的节点。显然,如果x=y, f[x][y] =0,如果猫走的时候已经抓到了老鼠,那么 f[x][y]=1 ;
给出代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 1006
using namespace std;
int n,e,p1,p2,tot,lnk[maxn],son[maxn*2],nxt[maxn*2],ent[maxn],dis[maxn],que[maxn],
    p[maxn][maxn];
bool vis[maxn];
double INF,f[maxn][maxn];
int _read(){
    char ch=getchar();int sum=0;
    while(!(ch>='0'&&ch<='9'))ch=getchar();
    while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=getchar();
    return sum;
}
void add(int x,int y){
    nxt[++tot]=lnk[x];son[tot]=y;lnk[x]=tot;ent[x]++;
}
void bfs(int x){
    memset(vis,1,sizeof(vis));
    int hed=0,tal=1;que[1]=x;vis[x]=0;dis[x]=0;
    while(hed!=tal){
        for(int j=lnk[que[++hed]];j;j=nxt[j]) if(vis[son[j]]){
            que[++tal]=son[j];
            vis[son[j]]=0;
            dis[son[j]]=dis[que[hed]]+1;
        }
    }
}
double DP(int x,int y){
    if(x==y){return f[x][y]=0;}
    if(f[x][y]!=INF)return f[x][y];
    if(p[x][y]==y)return f[x][y]=1;
    if(p[p[x][y]][y]==y)return f[x][y]=1;
    f[x][y]=1;
    f[x][y]+=DP(p[p[x][y]][y],y)/(ent[y]+1);
    for(int j=lnk[y];j;j=nxt[j])if(son[j]!=x)
     if(p[x][son[j]]!=son[j]) f[x][y]+=DP(p[p[x][y]][y],son[j])/(ent[y]+1);
    return f[x][y];
}
int main(){
    freopen("forest.in","r",stdin);
    freopen("forest.out","w",stdout);
    n=_read();e=_read();p1=_read();p2=_read();
    for(int i=1,x,y;i<=e;i++)x=_read(),y=_read(),add(x,y),add(y,x);
    memset(p,63,sizeof(p));memset(f,127,sizeof(f));INF=f[0][0];
    for(int i=1;i<=n;i++){
        bfs(i);
        for(int j=1;j<=n;j++)
         for(int k=lnk[j];k;k=nxt[k]) if((dis[son[k]]+1==dis[j])&&(son[k]<p[j][i]))p[j][i]=son[k];
    }
    printf("%.3lf",DP(p1,p2));
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值