• bzoj 1415


    莫名互测题...

    这题一看就是期望dp,可是不会转移,所以考试写50分暴力走人...

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <stack>
    using namespace std;
    struct Edge
    {
      int next;
      int to;
    }edge[2005];
    int head[1005];
    int dis[1005][1005];
    bool used[1005];
    int cnt=1;
    int n,m;
    int p0,p1;
    void init()
    {
      memset(head,-1,sizeof(head));
      cnt=1;
    }
    void add(int l,int r)
    {
      edge[cnt].next=head[l];
      edge[cnt].to=r;
      head[l]=cnt++;
    }
    void spfa(int rt)
    {
      queue <int> M;
      memset(dis[rt],0x3f,sizeof(dis[rt]));
      memset(used,0,sizeof(used));
      dis[rt][rt]=0;
      used[rt]=1;
      M.push(rt);
      while(!M.empty())
        {
          int u=M.front();
          M.pop();
          for(int i=head[u];i!=-1;i=edge[i].next)
    	{
    	  int to=edge[i].to;
    	  if(dis[rt][to]>dis[rt][u]+1)
    	    {
    	      dis[rt][to]=dis[rt][u]+1;
    	      if(!used[to])
    		{
    		  used[to]=1;
    		  M.push(to);
    		}
    	    }
    	}
        }
    }
    double ans=0;
    void dfs(double p,int v,int pr,int pz)
    {
      if(pr==pz)
        {
          ans+=(double)v*p;
          return;
        }
      int maxp=0;
      int temp=0x3f3f3f3f;
      for(int i=head[pr];i!=-1;i=edge[i].next)
        {
          int to=edge[i].to;
          if(dis[to][pz]<temp)
    	{
    	  temp=dis[to][pz];
    	  maxp=to;
    	}else if(dis[to][pz]==temp)
    	{
    	  maxp=min(maxp,to);
    	}
        }
      pr=maxp;
      if(pr==pz)
        {
          ans+=(double)v*p;
          return;
        }
      maxp=0;
      temp=0x3f3f3f3f;
      for(int i=head[pr];i!=-1;i=edge[i].next)
        {
          int to=edge[i].to;
          if(dis[to][pz]<temp)
    	{
    	  temp=dis[to][pz];
    	  maxp=to;
    	}else if(dis[to][pz]==temp)
    	{
    	  maxp=min(maxp,to);
    	}
        }
      pr=maxp;
      if(pr==pz)
        {
          ans+=(double)v*p;
          return;
        }
      int cot=0;
      for(int i=head[pz];i!=-1;i=edge[i].next)
        {
          cot++;
        }
      cot++;
      for(int i=head[pz];i!=-1;i=edge[i].next)
        {
          int to=edge[i].to;
          if(to==pr)
    	{
    	  ans+=(double)p*(double)1.0/(double)cot*(double)v;
    	  continue;
    	}
          dfs(p*(double)1.0/(double)cot,v+1,pr,to);
        }
      dfs(p*(double)1.0/(double)cot,v+1,pr,pz);
    }
    int main()
    {
    // freopen("eat.in","r",stdin);
    //  freopen("eat.out","w",stdout);
      scanf("%d%d",&n,&m);
      scanf("%d%d",&p0,&p1);
      if(p0==p1)
        {
          printf("0
    ");
          return 0;
        }
      init();
      for(int i=1;i<=m;i++)
        {
          int x,y;
          scanf("%d%d",&x,&y);
          add(x,y);
          add(y,x);
        }
      for(int i=1;i<=n;i++)
        {
          spfa(i);
        }
      dfs(1,1,p0,p1);
      printf("%.3lf
    ",ans);
      return 0;
    }
    

    正解:期望dp+记忆华搜索 

    设状态f[i][j]代表聪聪在i点,可可在j点时聪聪追上可可的期望

    然后用dfs更新即可,注意先预处理出最短路和tpos[i][j]表示聪聪在i点,可可在j点时聪聪走一步时会走到的位置

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <stack>
    using namespace std;
    struct Edge
    {
        int next;
        int to;
    }edge[2005];
    int head[1005];
    int cnt=1;
    int dis[1005][1005];
    int tpos[1005][1005];
    double f[1005][1005];
    bool used[1005];
    int inr[1005];
    int n,m,p0,p1;
    void add(int l,int r)
    {
        edge[cnt].next=head[l];
        edge[cnt].to=r;
        head[l]=cnt++;
    }
    void bfs(int rt)
    {
        queue <int> M;
        memset(used,0,sizeof(used));
        memset(dis[rt],0x3f,sizeof(dis[rt]));
        M.push(rt);
        dis[rt][rt]=0;
        used[rt]=1;
        while(!M.empty())
        {
            int u=M.front();
            M.pop();
            for(int i=head[u];i;i=edge[i].next)
            {
                int to=edge[i].to;
                if(used[to])
                {
                    continue;
                }
                used[to]=1;
                dis[rt][to]=dis[rt][u]+1;
                M.push(to);
            }
        }
    }
    double dfs(int pr,int pz)
    {
        if(f[pr][pz]!=-1.0)
        {
            return f[pr][pz];
        }
        if(pr==pz)
        {
            return f[pr][pz]=0.0;
        }
        if(tpos[pr][pz]==pz)
        {
            return f[pr][pz]=1.0;
        }
        if(tpos[tpos[pr][pz]][pz]==pz)
        {
            return f[pr][pz]=1.0;
        }
        f[pr][pz]=0.0;
        for(int i=head[pz];i;i=edge[i].next)
        {
            int to=edge[i].to;
            f[pr][pz]+=dfs(tpos[tpos[pr][pz]][pz],to);
        }
        f[pr][pz]=(f[pr][pz]+dfs(tpos[tpos[pr][pz]][pz],pz))/(double)inr[pz]+1;
        return f[pr][pz];
    }
    inline int read()
    {
    	int f=1,x=0;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    	return x*f;
    }
    int main()
    {
    //	freopen("eat.in","r",stdin);
    //	freopen("eat.out","w",stdout);
        n=read(),m=read();
        p0=read(),p1=read();
        for(int i=1;i<=m;i++)
        {
            int x=read(),y=read();
            add(x,y);
            add(y,x);
            inr[x]++;
            inr[y]++;
        }
        for(int i=1;i<=n;i++)
        {
            inr[i]++;
            bfs(i);
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                f[i][j]=-1.0;
                int temp=0x3f3f3f3f;
                for(int k=head[i];k;k=edge[k].next)
                {
                    int to=edge[k].to;
                    if(dis[to][j]<temp)
                    {
                        tpos[i][j]=to;
                        temp=dis[to][j];
                    }else if(dis[to][j]==temp)
                    {
                        tpos[i][j]=min(tpos[i][j],to);
                    }
                }		
            }
        }
        printf("%.3lf
    ",dfs(p0,p1));
        return 0;
    }
  • 相关阅读:
    Maven工程无异常 启动没有出现Starting ProtocolHandler的原因
    Unknown return value type [java.lang.Boolean]] with root cause
    解决java.lang.IllegalArgumentException: No converter found for return value of type
    jsp页面的地址
    HTTP Status 500
    Could not resolve placeholder 'IMAGE_SERVER_URL' in string value "${IMAGE_SERVER_URL}"
    yum出现Loaded plugins: fastestmirror, security Loading mirror speeds from cached hostfile解决方法
    【程序人生】百度员工应聘腾讯职位,结果亮了!
    【开源组件】FastDFS集群搭建与实战
    【开源组件】FastDFS极速入门与安装
  • 原文地址:https://www.cnblogs.com/zhangleo/p/10764189.html
Copyright © 2020-2023  润新知