BZOJ 1415 聪聪和可可 NOI2005

Problem

BZOJ

Solution

首先我们可以直接bfs预处理出nxt[i][j],其表示聪聪在i节点,可可在j节点时,聪聪下一步将去往的节点,那么我们就只需要考虑可可的走的可能性。
不妨设f[i][j]表示当聪聪在i节点,可可在j节点时,期望要走的步数。首先边界情况是f[i][i]=0,直接考虑其状态转移方程,枚举各种状态。
在这里,我们用nxt表示走了两步之后到达的节点,注意是聪聪先走

f [ i ] [ j ] = f [ n x t ] [ j ] + j > k f [ n x t ] [ k ] d [ j ] + 1 + 1

我们可以很方便地用记忆化搜索解决。

Code

#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
const int maxn=1010,INF=0x3f3f3f3f;
const double eps=1e-8;
struct data{int v,nxt;}edge[maxn<<1];
int n,m,s,t,p,d[maxn],head[maxn],dis[maxn],nxt[maxn][maxn];
double f[maxn][maxn];
queue<int> q;
inline double abs(double x){return x<0?-x:x;}
inline void insert(int u,int v)
{
    edge[++p]=(data){v,head[u]};head[u]=p;
    edge[++p]=(data){u,head[v]};head[v]=p;
}
void input()
{
    int u,v;
    scanf("%d%d%d%d",&n,&m,&s,&t);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&u,&v);
        insert(u,v);d[u]++;d[v]++;
    }
}
void get(int k)
{
    int x;
    while(!q.empty()) q.pop();
    memset(dis,0x3f,sizeof(dis));
    q.push(k);dis[k]=0;nxt[k][k]=k;
    while(!q.empty())
    {
        x=q.front();q.pop();
        for(int i=head[x];i;i=edge[i].nxt)
        {
            if(dis[edge[i].v]==INF)
            {
                dis[edge[i].v]=dis[x]+1;
                nxt[edge[i].v][k]=x;
                q.push(edge[i].v);
            }
            else if(dis[edge[i].v]==dis[x]+1&&nxt[edge[i].v][k]>x)
              nxt[edge[i].v][k]=x;
        }
    }
}
double dp(int x,int y)
{
    if(abs(f[x][y]+1)>eps) return f[x][y];
    if(x==y) return f[x][y]=0.0;
    if(nxt[x][y]==y||nxt[nxt[x][y]][y]==y) return f[x][y]=1.0;
    f[x][y]=0.0;
    for(int i=head[y];i;i=edge[i].nxt)
      f[x][y]+=dp(nxt[nxt[x][y]][y],edge[i].v);
    f[x][y]=(f[x][y]+dp(nxt[nxt[x][y]][y],y))/(double)(d[y]+1)+1.0;
    return f[x][y];
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif
    input();
    for(int i=1;i<=n;i++) get(i);
    memset(f,-1,sizeof(f));
    printf("%.3lf\n",dp(s,t));
    return 0;
}

猜你喜欢

转载自blog.csdn.net/As_A_Kid/article/details/80355911