zoukankan      html  css  js  c++  java
  • BZOJ1415: [Noi2005]聪聪和可可 最短路 期望概率dp

    首先这道题让我回忆了一下最短路算法,所以我在此做一个总结:

    带权: Floyed:O(n3)

               SPFA:O(n+m),这是平均复杂度实际上为O(玄学)

               Dijkstra:O(n+2m),堆优化以后

              因此,稀疏图:SPFA或 Dijkstra可以再大约O(n2)左右的时间跑完每个点到每个点的最短路

                      稠密图:啥也别说 Floyed

    不带权(边权为1):SPFA=Dijkstra(堆优化)=BFS=O(n+2m) ,这个是真的差距只有常数

                                      Floyed:O(n3)

                                     因此,同上

    从这个题我得出来一点期望概率dp的小思路:找到各个状态间的核心逻辑关系

    这个题就是 f[cat][mouse]=∑f[cat一下子扑到][mouse走到]

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #define MAXN 1010
    using namespace std;
    typedef double D;
    D f[MAXN][MAXN];
    int n,m,s,e,d[MAXN][MAXN],dis[MAXN][MAXN],via[MAXN][MAXN],q[MAXN],head,tail,sz,now;
    struct Two
    {
        int a,b;
    }two[MAXN*MAXN];
    int comp(const Two a,const Two b)
    {
         return dis[a.a][a.b]<dis[b.a][b.b];
    }
    inline void blabla()
    {
        for(int i=1;i<=n;i++)
         for(int j=1;j<=n;j++)
          printf("%d live %d with %lf
    ",i,j,f[i][j]);
    }
    inline void bfs(int st)
    {
        head=1;
        tail=0;
        q[++tail]=st;
        while(tail>=head)
        {
          int x=q[head++];
          for(int i=1;i<=via[x][0];i++)
          if(dis[st][via[x][i]]==0&&via[x][i]!=st)
          {
            dis[st][via[x][i]]=dis[st][x]+1;
            if(dis[st][via[x][i]]<=2) d[st][via[x][i]]=via[x][i];
            else d[st][via[x][i]]=d[st][x];
            q[++tail]=via[x][i];
          }
        }
    }
    void pre()
    {
        scanf("%d%d%d%d",&n,&m,&s,&e);
        for(int i=1;i<=m;i++)
        {
          int x,y;
          scanf("%d%d",&x,&y);
          via[x][++via[x][0]]=y;
          via[y][++via[y][0]]=x;
        }
        for(int i=1;i<=n;i++)
         sort(via[i]+1,via[i]+via[i][0]+1);
        for(int i=1;i<=n;i++)
         bfs(i);
        for(int i=1;i<=n;i++)
         for(int j=1;j<=n;j++)
          if(i!=j)
          {
             two[++sz].a=i;
             two[sz].b=j;
          }
        sort(two+1,two+sz+1,comp);
    }
    void work()
    {
        now=0;
        while(now<=sz)
        {
          ++now;       
          if(dis[two[now].a][two[now].b]<=2)
          {
             f[two[now].a][two[now].b]=1.0;
             continue;
          }
          int x=d[two[now].a][two[now].b],y=two[now].b;
          f[two[now].a][two[now].b]+=f[x][y]*1.0/(1.0+via[y][0]*1.0)+1.0;
          for(int i=1;i<=via[y][0];i++)
             f[two[now].a][two[now].b]+=f[x][via[y][i]]*1.0/(1.0+via[y][0]);
        }
    }
    int main()
    {
        freopen("cchkk.in","r",stdin);
        freopen("cchkk.out","w",stdout);
        pre();
        work();
        printf("%.3lf",f[s][e]);
        return 0;
    }
  • 相关阅读:
    php 换行 PHP_EOL
    removeAttribute与removeAttributeNode的区别
    百度地图api 常用 例子
    nth-child()伪类选择器
    c++ 11 lambda表达式
    mysql sql时间戳格式化语句
    Apache Forbidden 403错误提示
    MySQL中查询所有数据库占用磁盘空间大小
    luaj使用 方法签名规则 Cocos2dxLuaJavaBridge
    nginx代理配置备份
  • 原文地址:https://www.cnblogs.com/TSHugh/p/7081318.html
Copyright © 2011-2022 走看看