【题解】bzoj-1415 NOI-2005 聪聪与可可

Problem

Luogu&bzoj

Solution

这题一看就联想起了HNOI游走那道题,仔细一看发现不对

发现这题的转移是有终点的,所以可以用Dp,加上题目是一张图,推荐用记忆化搜索

显然想到 f [ i ] [ j ] 表示当聪聪在点 i 可可在点 j 时聪聪抓可可步数的期望,先预处理聪聪在 i 可可在 j 时聪聪的选择路径 t [ i ] [ j ]
方程:

f [ i ] [ j ] = f [ t [ t [ i ] [ j ] ] [ j ] ] [ j ] + f [ t [ t [ i ] [ j ] ] [ j ] ] [ v ] d e g [ j ] + 1 + 1

边界情况是 f [ i ] [ i ] = 0 ,如果 i , j 两步之内可达 f [ i ] [ j ] = 1

Code

#include<cctype>
#include<cstdio>
using namespace std;
#define rg register

template <typename _Tp> inline _Tp read(_Tp&x){
    rg char c11=getchar(),ob=0;x=0;
    while(c11^'-'&&!isdigit(c11))c11=getchar();if(c11=='-')c11=getchar(),ob=1;
    while(isdigit(c11))x=x*10+c11-'0',c11=getchar();if(ob)x=-x;return x;
}

const int N=1050;
struct Edge{int v,nxt;}a[N<<1];
int head[N],deg[N],dis[N][N],to[N][N],q[N],he,ta;
double f[N][N];
int n,m,_;

inline void add(int u,int v){a[++_].v=v,a[_].nxt=head[u],head[u]=_,++deg[u];}

double dfs(int x,int y){
    if(f[x][y]!=-1.0)return f[x][y];
    if(x==y)return f[x][y]=0;
    if(to[x][y]==y)return f[x][y]=1;
    if(to[to[x][y]][y]==y)return f[x][y]=1;
    f[x][y]=0.0;
    f[x][y]+=dfs(to[to[x][y]][y],y);
    for(int i=head[y];i;i=a[i].nxt)
        f[x][y]+=dfs(to[to[x][y]][y],a[i].v);
    f[x][y]=f[x][y]/(double)(deg[y]+1)+1;
    return f[x][y];
}

int main(){
    int sa,sb;
    read(n),read(m);
    read(sa),read(sb);
    for(rg int i=0,x,y;i<m;++i)read(x),read(y),add(x,y),add(y,x);

    for(rg int i=1;i<=n;++i)
    for(rg int j=1;j<=n;++j)f[i][j]=-1.0,to[i][j]=dis[i][j]=-1;

    for(rg int s=1;s<=n;++s){
        q[he=ta=1]=s;dis[s][s]=0;
        while(he<=ta){
            int x=q[he++];
            for(int i=head[x];i;i=a[i].nxt)
                if(-1==dis[s][a[i].v])
                    dis[s][a[i].v]=dis[s][x]+1,q[++ta]=a[i].v;
        }
    }
    for(rg int x=1;x<=n;++x)
    for(rg int t=1;t<=n;++t)if(x!=t&&dis[x][t]!=-1)
        for(rg int i=head[x];i;i=a[i].nxt)
            if(dis[x][t]==dis[a[i].v][t]+1&&(a[i].v<to[x][t]||to[x][t]==-1))
                to[x][t]=a[i].v;
    printf("%.3lf\n",dfs(sa,sb));
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40515553/article/details/80357708