bzoj1415 [Noi2005]聪聪和可可——概率期望

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1415

看博客:http://www.cnblogs.com/Narh/p/9206642.html

看博客:https://blog.csdn.net/clove_unique/article/details/62237321

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int const maxn=1005;
int n,m,cc,kk,head[maxn],ct,dis[maxn][maxn],goal[maxn][maxn],inf;
double d[maxn],f[maxn][maxn],ans;
queue<int>q;
struct N{
    int to,next;
    N(int t=0,int n=0):to(t),next(n) {}
}edge[maxn<<1];
void add(int x,int y){edge[++ct]=N(y,head[x]); head[x]=ct;}
void bfs(int s)
{
    while(q.size())q.pop();
    dis[s][s]=0; q.push(s);
    while(q.size())
    {
        int x=q.front(); q.pop();
        for(int i=head[x];i;i=edge[i].next)
        {
            int u=edge[i].to;
            if(dis[s][u]==inf)
            {
                dis[s][u]=dis[s][x]+1;
                q.push(u);
            }
        }
    }
}
double dfs(int c,int k)
{
    if(f[c][k]>=0)return f[c][k];
    if(c==k)return f[c][k]=0;
    if(dis[c][k]<=2)return f[c][k]=1;
    double P=1.0/(d[k]+1.0);
    f[c][k]=1;//
    int to=goal[c][k];
    for(int i=head[k];i;i=edge[i].next)
        f[c][k]+=P*dfs(to,edge[i].to);
    f[c][k]+=P*dfs(to,k);
    return f[c][k];
}
int main()
{
    scanf("%d%d%d%d",&n,&m,&cc,&kk);
    for(int i=1,x,y;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        add(x,y); add(y,x);
        d[x]+=1.0; d[y]+=1.0;
    }
    memset(dis,0x3f,sizeof dis); inf=dis[0][0];
    for(int i=1;i<=n;i++)bfs(i);
    for(int i=1;i<=n;i++)//cc
        for(int j=1;j<=n;j++)//kk
        {
            if(dis[i][j]==inf)continue;
            if(dis[i][j]<=2){goal[i][j]=j; continue;}
            int mx=inf,t=inf;
            for(int k=head[i];k;k=edge[k].next)
            {
                int u=edge[k].to;
                if(dis[u][j]<mx || (dis[u][j]==mx&&u<t))mx=dis[u][j],t=u;
            }
            int mx2=inf,t2=inf;
            for(int k=head[t];k;k=edge[k].next)
            {
                int u=edge[k].to;
                if(dis[u][j]<mx2 || (dis[u][j]==mx2&&u<t2))mx2=dis[u][j],t2=u;
            }
            goal[i][j]=t2;
        }
    memset(f,-3,sizeof f);
    ans=dfs(cc,kk);
    printf("%.3lf",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Zinn/p/9249112.html