题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1415

乍一看和“游走”一样。于是高斯消元。n^2状态,复杂度n^6……

看看TJ,发现因为聪聪不是随便走的,所以聪聪一直逼近可可。故其实无环。可以记搜。

(1A还是不错的)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=;
int n,m,l0,l1,nxt[N][N],dfn[N],du[N];
double dp[N][N];
bool vis[N],vs[N][N];
priority_queue<int,vector<int>,greater<int> >ed[N];
void add(int x,int y)
{
ed[x].push(y);ed[y].push(x);
du[x]++;du[y]++;
}
void bfs(int cr)
{
priority_queue<int,vector<int>,greater<int> >tp;
memset(vis,,sizeof vis);memset(dfn,,sizeof dfn);
queue<int> q;q.push(cr);vis[cr]=;nxt[cr][cr]=cr;
while(q.size())
{
int k=q.front();q.pop();
tp=ed[k];
while(tp.size())
{
int v=tp.top();tp.pop();
if(vis[v])continue;
dfn[v]=dfn[k]+;vis[v]=;q.push(v);
if(dfn[v]>)nxt[v][cr]=nxt[k][cr];
else nxt[v][cr]=v;
}
}
}
double dfs(int x,int y)//coco->x ,cncn->y
{
// printf("x=%d y=%d\n",x,y);
if(vs[x][y])return dp[x][y];vs[x][y]=;
if(nxt[x][y]==x){/*printf("rt x=%d y=%d\n",x,y);*/return dp[x][y]=;}
double ret=(dfs(x,nxt[x][y])+(nxt[x][y]!=x))/(du[x]+);
priority_queue<int,vector<int>,greater<int> >tp=ed[x];//每层定义
// printf("siz[%d]=%d\n",x,tp.size());
while(tp.size())
{
int v=tp.top();tp.pop();
// printf("v=%d nxt[%d][%d]=%d\n",v,x,y,nxt[x][y]);
ret+=(dfs(v,nxt[x][y])+(nxt[x][y]!=v))/(du[x]+);
}
// printf("ret=%.3lf\n",ret);
return dp[x][y]=ret;
}
int main()
{
scanf("%d%d%d%d",&n,&m,&l0,&l1);int x,y;
for(int i=;i<=m;i++)
{
scanf("%d%d",&x,&y);add(x,y);
}
for(int i=;i<=n;i++)bfs(i);
printf("%.3lf",dfs(l1,l0));
return ;
}

版本1

看看TJ,发现判断得那么纠结是因为x==y时正常应返回0。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=;
int n,m,l0,l1,nxt[N][N],dfn[N],du[N];
double dp[N][N];
bool vis[N],vs[N][N];
priority_queue<int,vector<int>,greater<int> >ed[N];
void add(int x,int y)
{
ed[x].push(y);ed[y].push(x);
du[x]++;du[y]++;
}
void bfs(int cr)
{
priority_queue<int,vector<int>,greater<int> >tp;
memset(vis,,sizeof vis);memset(dfn,,sizeof dfn);
queue<int> q;q.push(cr);vis[cr]=;nxt[cr][cr]=cr;
while(q.size())
{
int k=q.front();q.pop();
tp=ed[k];
while(tp.size())
{
int v=tp.top();tp.pop();
if(vis[v])continue;
dfn[v]=dfn[k]+;vis[v]=;q.push(v);
if(dfn[v]>)nxt[v][cr]=nxt[k][cr];
else nxt[v][cr]=v;
}
}
}
double dfs(int x,int y)//coco->x ,cncn->y
{
if(vs[x][y])return dp[x][y];vs[x][y]=;
if(x==y)return dp[x][y]=;//
if(nxt[x][y]==x)return dp[x][y]=;
double ret=dfs(x,nxt[x][y])/(du[x]+)+;
priority_queue<int,vector<int>,greater<int> >tp=ed[x];//每层定义
while(tp.size())
{
int v=tp.top();tp.pop();
ret+=dfs(v,nxt[x][y])/(du[x]+);
}
return dp[x][y]=ret;
}
int main()
{
scanf("%d%d%d%d",&n,&m,&l0,&l1);int x,y;
for(int i=;i<=m;i++)
{
scanf("%d%d",&x,&y);add(x,y);
}
for(int i=;i<=n;i++)bfs(i);
printf("%.3lf",dfs(l1,l0));
return ;
}

版本2

但是自己代码巨慢……想来是用了优先队列的缘故(为了标号字典序)。尝试改一改。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=;
int n,m,l0,l1,nxt[N][N],dfn[N],du[N],head[N],xnt;
double dp[N][N];
bool vis[N],vs[N][N];
priority_queue<int,vector<int>,greater<int> >ed[N];
struct Edge{
int next,to;
Edge(int n=,int t=):next(n),to(t) {}
}edge[N<<];
void add(int x,int y)
{
edge[++xnt]=Edge(head[x],y);head[x]=xnt;
edge[++xnt]=Edge(head[y],x);head[y]=xnt;
ed[x].push(y);ed[y].push(x);
du[x]++;du[y]++;
}
void bfs(int cr)
{
priority_queue<int,vector<int>,greater<int> >tp;
memset(vis,,sizeof vis);memset(dfn,,sizeof dfn);
queue<int> q;q.push(cr);vis[cr]=;nxt[cr][cr]=cr;
while(q.size())
{
int k=q.front();q.pop();
tp=ed[k];
while(tp.size())
{
int v=tp.top();tp.pop();
if(vis[v])continue;
dfn[v]=dfn[k]+;vis[v]=;q.push(v);
if(dfn[v]>)nxt[v][cr]=nxt[k][cr];
else nxt[v][cr]=v;
}
}
}
double dfs(int x,int y)//coco->x ,cncn->y
{
if(vs[x][y])return dp[x][y];vs[x][y]=;
if(x==y)return dp[x][y]=;//
if(nxt[x][y]==x)return dp[x][y]=;
double ret=dfs(x,nxt[x][y])/(du[x]+)+;
for(int i=head[x];i;i=edge[i].next)
ret+=dfs(edge[i].to,nxt[x][y])/(du[x]+);
return dp[x][y]=ret;
}
int main()
{
scanf("%d%d%d%d",&n,&m,&l0,&l1);int x,y;
for(int i=;i<=m;i++)
{
scanf("%d%d",&x,&y);add(x,y);
}
for(int i=;i<=n;i++)bfs(i);
printf("%.3lf",dfs(l1,l0));
return ;
}

结果只是快了28ms。

别人用一些方法保证字典序。

这个人bfs+两步保证dis最小的前提下调整标号至最小。https://blog.csdn.net/clove_unique/article/details/62237321

这个人spfa的同时判断标号。(但只能记录一步的pre)https://blog.csdn.net/PoPoQQQ/article/details/40896403(bfs因为是bfs所以不能边求dis边调整标号)

可是我都没记录dis。用的dfn。所以懒得改了……比较欣赏第一个人的写法。

bzoj 1415 [Noi2005]聪聪和可可——其实无环的图上概率的更多相关文章

  1. BZOJ 1415: [Noi2005]聪聪和可可( 最短路 + 期望dp )

    用最短路暴力搞出s(i, j)表示聪聪在i, 可可在j处时聪聪会走的路线. 然后就可以dp了, dp(i, j) = [ dp(s(s(i,j), j), j) + Σdp(s(s(i,j), j), ...

  2. BZOJ 1415 [NOI2005]聪聪与可可 (概率DP+dfs)

    题目大意:给你一个无向联通图,节点数n<=1000.聪聪有一个机器人从C点出发向在M点的可可移动,去追赶并吃掉可可,在单位时间内,机器人会先朝离可可最近的节点移动1步,如果移动一步机器人并不能吃 ...

  3. BZOJ 1415: [Noi2005]聪聪和可可 [DP 概率]

    传送门 题意:小兔子乖乖~~~ 题意·真:无向图吗,聪抓可,每个时间聪先走可后走,聪一次可以走两步,朝着里可最近且点编号最小的方向:可一次只一步,等概率走向相邻的点或不走 求聪抓住可的期望时间 和游走 ...

  4. bzoj 1415: [Noi2005]聪聪和可可 期望dp+记忆化搜索

    期望dp水题~ 你发现每一次肯定是贪心走 2 步,(只走一步的话就可能出现环) 然后令 $f[i][j]$ 表示聪在 $i$,可在 $j$,且聪先手两个人碰上面的期望最小次数. 用记忆化搜索转移就行了 ...

  5. bzoj 1415: [Noi2005]聪聪和可可

    直接上记忆化搜索 #include<queue> #include<cstdio> #include<algorithm> using namespace std; ...

  6. bzoj 1415: [Noi2005]聪聪和可可【期望dp+bfs】

    因为边权为1所以a直接bfs瞎搞就行--我一开始竟然写了个spfa #include<iostream> #include<cstdio> #include<queue& ...

  7. BZOJ 1415: [Noi2005]聪聪和可可(记忆化搜索+期望)

    传送门 解题思路 还是比较简答的一道题.首先\(bfs\)把每个点到其他点的最短路求出来,然后再记忆化搜索.记搜的时候猫的走法是确定的,搜一下老鼠走法就行了. 代码 #include<iostr ...

  8. 【BZOJ】【1415】【NOI2005】聪聪和可可

    数学期望+记忆化搜索 论文:<浅析竞赛中一类数学期望问题的解决方法>——汤可因  中的第一题…… Orz 黄学长 我实在是太弱,这么简单都yy不出来…… 宽搜预处理有点spfa的感觉= = ...

  9. 【BZOJ 1415】 1415: [Noi2005]聪聪和可可 (bfs+记忆化搜索+期望)

    1415: [Noi2005]聪聪和可可 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1640  Solved: 962 Description I ...

随机推荐

  1. tcp连接的建立与释放

    1.TCP是面向连接的协议. 运输连接时用来传送TCP报文的.TCP运输连接的建立和释放是每一次面向连接的通信中必不可少的过程.因此,运输链接就有三个阶段,即:连接建立.数据传送和连接释放. 在TCP ...

  2. spring通知的注解

    1.代理类接口Person.java package com.xiaostudy; /** * @desc 被代理类接口 * * @author xiaostudy * */ public inter ...

  3. Jar 包 及运行Jar包 - 转载

    Eclipse的jar file和Runnable JAR file的区别 - 及bat运行Runnable JAR文件 1.两种jar的区别 jar file是最普通的jar包,即平时我们工程中li ...

  4. 【Boost】boost库asio详解5——resolver与endpoint使用说明

    tcp::resolver一般和tcp::resolver::query结合用,通过query这个词顾名思义就知道它是用来查询socket的相应信息,一般而言我们关心socket的东东有address ...

  5. Android -- 读写文件到内部ROM,SD卡,SharedPreferences,文件读写权限

    (内容整理自张泽华教程) 1. 概述 使用文件进行数据存储 首先给大家介绍使用文件如何对数据进行存储,Activity提供了openFileOutput()方法可以用于把数据输出到文件中,具体的实现过 ...

  6. CSS设置小技巧

    水平居中 对于元素的水平居中,有三种情况: 行内元素(文字.图片等):text-align: center; 定宽块状元素(有设置宽度的block元素):margin: 0 auto; 不定宽块状元素 ...

  7. 远程调用之RMI、Hessian、Burlap、Httpinvoker、WebService的比较

    一.综述 本文比较了RMI.Hessian.Burlap.Httpinvoker.WebService5这种通讯协议的在不同的数据结构和不同数据量时的传输性能. RMI是java语言本身提供的远程通讯 ...

  8. Ceph配置项动态变更机制浅析

    转自:https://www.ustack.com/blog/ceph%e9%85%8d%e7%bd%ae%e9%a1%b9%e5%8a%a8%e6%80%81%e5%8f%98%e6%9b%b4%e ...

  9. IOS-视频

    一.简介 iOS提供了MPMoviePlayerController.MPMoviePlayerViewController两个类,可以用来轻松播放视频和网络流媒体\网络音频 提示:网络音频同样使用此 ...

  10. Hadoop WordCount程序

    一.把所有Hadoop的依赖jar包导入buildpath,不用一个一个调,都导一遍就可以,因为是一个工程,所以覆盖是没有问题的 二.写wordcount程序 1.工程目录结构如下: 2.写mappe ...