zoukankan      html  css  js  c++  java
  • [NOI2005]聪聪与可可

    题目大意:有小a和小b,其中一个人到处乱走,每次走一步;另一个人抄近路逼近,每次1-2步。求期望路程。

    整解:跑1000遍最短路/bfs,求两两距离,然后找从x逼近y第一步去哪,最后期望dp收场。

    dp方程很简单,关键在于实现。

    代码:

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define N 1050
    int n,E,xr,xz,hed[N],cnt;
    double ind[N];
    struct EG
    {
        int to,nxt;
    }e[2*N];
    void ae(int f,int t)
    {
        e[++cnt].to = t;
        e[cnt].nxt = hed[f];
        hed[f] = cnt;
    }
    int dis[N][N],chos[N][N];
    bool vis[N];
    struct node
    {
        int x,d;
        node(){}
        node(int x,int d):x(x),d(d){}
        friend bool operator < (node a,node b)
        {
            return a.d>b.d;
        }
    }tp;
    priority_queue<node>q;
    void dij(int rt)
    {
        dis[rt][rt]=0;
        memset(vis,0,sizeof(vis));
        q.push(node(rt,0));
        while(!q.empty())
        {
            tp = q.top();
            q.pop();
            int u = tp.x;
            if(vis[u])continue;
            vis[u]=1;
            for(int j=hed[u];j;j=e[j].nxt)
            {
                int to = e[j].to;
                if(dis[rt][to]>dis[rt][u]+1)
                {
                    dis[rt][to]=dis[rt][u]+1;
                    q.push(node(to,dis[rt][to]));
                }
            }
        }
    }
    double f[N][N];
    double dp(int x,int y)
    {
        if(f[x][y]+1.0!=0)return f[x][y];
        if(x==y)return f[x][y]=0.0;
        if(dis[x][y]<=2)return f[x][y]=1.0;
        f[x][y]=0;
        int k = chos[chos[x][y]][y];//走两步 
        for(int j=hed[y];j;j=e[j].nxt)
            f[x][y]+=dp(k,e[j].to);
        f[x][y]+=dp(k,y);
        f[x][y] = (f[x][y]/(ind[y]+1.0))+1.0;
        return f[x][y];
    }
    int main()
    {
    //    freopen("eat.in","r",stdin);
    //    freopen("eat.out","w",stdout);
        scanf("%d%d%d%d",&n,&E,&xr,&xz);
        for(int u,v,i=1;i<=E;i++)
        {
            scanf("%d%d",&u,&v);
            ae(u,v),ae(v,u);
            ind[u]++,ind[v]++;
        }
        memset(dis,0x3f,sizeof(dis));
        for(int i=1;i<=n;i++)
            dij(i);
        memset(chos,0x3f,sizeof(chos));
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(dis[i][j]==0x3f3f3f3f||i==j)continue;
                for(int k=hed[i];k;k=e[k].nxt)
                {
                    int to = e[k].to;
                    if(dis[to][j]+1==dis[i][j]&&to<chos[i][j])
                        chos[i][j]=to;
                }
            }
        }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                f[i][j]=-1.0;
        printf("%.3lf
    ",dp(xr,xz));
        return 0;
    }
  • 相关阅读:
    AttributeError: module 'scipy.misc' has no attribute 'imread'
    3.形态学
    2.几何变换_图像金字塔
    ValueError:Object arrarys cannot be loaded when allow_pickle=False
    2.几何变换_切分合并通道
    2.几何变换_遮挡
    49. Group Anagrams
    151. Reverse Words in a String
    242. Valid Anagram
    227. Basic Calculator II
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/9743697.html
Copyright © 2011-2022 走看看