这道题之前我写过一个巨逗比的写法(传送门:http://www.cnblogs.com/liu-runda/p/6220381.html)

当时的原因是这道题可以抽象出和”绿豆蛙的归宿”差不多的模型,而我之前写”绿豆蛙的归宿”就是用的这个巨逗比的方法.

然后前几天看了@Sengxian的博客里”绿豆蛙的归宿”的写法(传送门:https://blog.sengxian.com/algorithms/probability-and-expected-value-dynamic-programming )发现”绿豆蛙的归宿”还可以用期望的线性性写,只需要求出经过每个点的概率(也就是期望次数,因为是DAG上所以这里经过的概率和期望次数是一样的),加起来就是总共期望经过的点数,点数-1就是期望步数.感觉非常兹瓷,于是写了写这个题,顺便试了一下之前口胡的把所有状态按最短路长度排序然后DP的方法,发现过不了….无用的状态太多了会TLE.把之前那个逗比程序(求出走到每个状态的概率和从起点到这个状态的期望步数),改了改过了(不过似乎没有快多少的样子,应该是因为之前逗比代码用的dijkstra...).

#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn=;
struct edge{
int to,next;
}lst[maxn<<];int len=,first[maxn];
void addedge(int a,int b){
lst[len].to=b;lst[len].next=first[a];
first[a]=len++;
}
double p[maxn][maxn],e[maxn][maxn];
int g[maxn][maxn],dis[maxn][maxn];
int n,m,s0,t0;
struct node{
int v,d;
node(int _v,int _d){v=_v;d=_d;}
bool operator <(const node &B)const{
return d>B.d;
}
};
int vis[maxn];
int T;
void dijkstra(int s,int dis[]){
++T;
priority_queue<node> q;
q.push(node(s,));
while(!q.empty()){
node tmp=q.top();q.pop();
if(vis[tmp.v]==T)continue;
vis[tmp.v]=T;dis[tmp.v]=tmp.d;
for(int pt=first[tmp.v];pt;pt=lst[pt].next){
if(vis[lst[pt].to]!=T)q.push(node(lst[pt].to,tmp.d+));
}
}
int ans;
for(int i=;i<=n;++i){
ans=i;
for(int pt=first[i];pt;pt=lst[pt].next){
if(dis[lst[pt].to]<dis[ans])ans=lst[pt].to;
if(dis[lst[pt].to]==dis[ans]&&lst[pt].to<ans)ans=lst[pt].to;
}
g[i][s]=ans;
}
}
int deg[maxn];
struct Node{
int s,t;
Node(int _s,int _t){s=_s;t=_t;}
Node(){};
}q[][maxn*maxn];//q[0]:-1 q[1]:-2 q[2]:-3
int head[],tail[];
bool used[maxn][maxn];
double ans=;
void bfs(){
while((head[]!=tail[])||(head[]!=tail[])||(head[]!=tail[])){
// getchar();printf("%d %d\n",head[0],tail[0]);
int tmp=-,Max=-;
for(int i=;i<;++i){
if(head[i]!=tail[i]&&dis[q[i][head[i]].s][q[i][head[i]].t]>Max){
tmp=i;Max=dis[q[i][head[i]].s][q[i][head[i]].t];
}
}
Node x=q[tmp][head[tmp]++];
ans+=p[x.s][x.t];
if(x.s==x.t)continue;
int s1=g[g[x.s][x.t]][x.t];
if(s1==x.t){
p[s1][x.t]+=p[x.s][x.t];//ans+=p[x.s][x.t];
if(!used[s1][x.t]){
used[s1][x.t]=true;
if(dis[x.s][x.t]==){
q[][tail[]++]=Node(s1,s1);
}else{
q[][tail[]++]=Node(s1,s1);
}
}
}else{
for(int pt=first[x.t];pt;pt=lst[pt].next){
p[s1][lst[pt].to]+=p[x.s][x.t]/deg[x.t];
if(!used[s1][lst[pt].to]){
used[s1][lst[pt].to]=true;
if(dis[s1][lst[pt].to]==dis[x.s][x.t]-)q[][tail[]++]=Node(s1,lst[pt].to);
else if(dis[s1][lst[pt].to]==dis[x.s][x.t]-)q[][tail[]++]=Node(s1,lst[pt].to);
else q[][tail[]++]=Node(s1,lst[pt].to);
}
}
// p[s1][x.t]+=p[x.s][x.t]/deg[x.t];
// if(q[1][tail[1]++]=Node(s1,x.t);
} }
}
int main(){
scanf("%d%d",&n,&m);
scanf("%d%d",&s0,&t0);
int a,b;
for(int i=;i<=m;++i){
scanf("%d%d",&a,&b);deg[a]++;deg[b]++;
addedge(a,b);addedge(b,a);
}
for(int i=;i<=n;++i){
deg[i]++;addedge(i,i);
dijkstra(i,dis[i]);
}
p[s0][t0]=1.0;
q[][tail[]++]=Node(s0,t0);
bfs();//get possibility
printf("%.3f\n",ans-);
return ;
}

bzoj1415[NOI2005]聪聪和可可-期望的线性性的更多相关文章

  1. 浅谈期望的线性性(可加性)【CodeForces280c】【bzoj3036】【bzoj3143】

    [pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=63399955 向大(hei)佬(e)势力学(di ...

  2. 【NOIP2019模拟2019.9.4】B(期望的线性性)

    题目描述: \(1<=n,ai<=5*10^5\) 题解: 我是弱智我不会期望线性. 设\(E(a[i])\)表示第i个期望被减的个数. \(E(a[1])=a[1]\) 不难发现\(E( ...

  3. 概率/期望DP初步——BZOJ1415 聪聪和可可

    期望相关: 数学期望,可以简单理解的加权平均数.设有一系列的值$x_i$,每个值被取到的概率为$p_i$,则期望$E=\sum\limits_{i=1}^n p_i x_i$. 期望具有线性性:$$E ...

  4. cf280C. Game on Tree(期望线性性)

    题意 题目链接 Sol 开始想的dp,发现根本不能转移(貌似只能做链) 根据期望的线性性,其中\(ans = \sum_{1 * f(x)}\) \(f(x)\)表示删除\(x\)节点的概率,显然\( ...

  5. 2019牛客暑期多校训练营(第八场)B-Beauty Values(期望线性性)

    >传送门< 题意:思路:期望的线性性(可加性),比赛的时候写的代码超级无敌长,不过值得欣慰的是一发AC了,官方的题解写的还不错~ 我们可以把每种数字对答案的贡献分开来计算,即枚举每个数字, ...

  6. 【BZOJ1415】【NOI2005】聪聪和可可(动态规划,数学期望)

    [BZOJ1415][NOI2005]聪聪和可可(动态规划,数学期望) 题面 BZOJ 题解 先预处理出当可可在某个点,聪聪在某个点时 聪聪会往哪里走 然后记忆化搜索一下就好了 #include< ...

  7. BZOJ1415[Noi2005]聪聪和可可——记忆化搜索+期望dp

    题目描述 输入 数据的第1行为两个整数N和E,以空格分隔,分别表示森林中的景点数和连接相邻景点的路的条数. 第2行包含两个整数C和M,以空格分隔,分别表示初始时聪聪和可可所在的景点的编号. 接下来E行 ...

  8. 【bzoj1415】[Noi2005]聪聪和可可 期望记忆化搜索

    题目描述 输入 数据的第1行为两个整数N和E,以空格分隔,分别表示森林中的景点数和连接相邻景点的路的条数. 第2行包含两个整数C和M,以空格分隔,分别表示初始时聪聪和可可所在的景点的编号. 接下来E行 ...

  9. BZOJ1415 [Noi2005]聪聪和可可 【SPFA + 期望dp记忆化搜索】

    题目 输入格式 数据的第1行为两个整数N和E,以空格分隔,分别表示森林中的景点数和连接相邻景点的路的条数. 第2行包含两个整数C和M,以空格分隔,分别表示初始时聪聪和可可所在的景点的编号. 接下来E行 ...

随机推荐

  1. 深入理解javascript选择器API系列第二篇——getElementsByClassName

    × 目录 [1]使用 [2]classList [3]扩展 前面的话 既然有getElementById()和getElementsByTagName()方法,为什么没有getElementsByCl ...

  2. iOS项目iCloud及CloudKit Dashboard运用

    CloudKit是苹果推出的基于iCloud的一个云端数据存储服务.其 主要由下面两部分组成: 一个仪表web页面,用于管理公开数据的记录类型. 一组API接口,用于iCloud和设备之间的数据传递. ...

  3. JSPatch来更新已上线的App中出现的BUG(超级详细)

    JSPatch的作用是什么呢? 简单来说:(后面有具体的操作步骤以及在操作过程中会出现的错误) 1.iOS应用程序上架到AppStore需要等待苹果公司的审核,一般审核时间需要1到2周.虽然程序在上架 ...

  4. [C#6] 1-using static

    0. 目录 C#6 新增特性目录 1. 老版本的代码 1 using System; 2 3 namespace csharp6 4 { 5 internal class Program 6 { 7 ...

  5. 【FLUENT案例】03:冲蚀

    1 引子2 问题描述3 模型准备4网格5模型设置6 材料设置7 设定注入器8 修改材料9 Cell zone Conditions设置10 边界条件设置10.1 inlet入口设置10.2 出口设置1 ...

  6. USACO . Your Ride Is Here

    Your Ride Is Here It is a well-known fact that behind every good comet is a UFO. These UFOs often co ...

  7. ongl(原始类型和包装类型)

    原始类型和包装类型 //首先创建两个实体类 user 和 address user中包含address package cn.jbit.bean; public class User { //用户类 ...

  8. Spring 框架的架包分析、功能作用、优点,及jar架包简介

    Spring 框架的架包详解    Spring的作用     Spring的优势  由于刚搭建完一个MVC框架,决定分享一下我搭建过程中学习到的一些东西.我觉得不管你是个初级程序员还是高级程序员抑或 ...

  9. struts-tags通用标签基本用法

    2017-01-07 16:02:46 <s:debug></s:debug><!-- 标签库中实现的debug --> ${name }<!-- 是从对象栈 ...

  10. Linux-./configure: error: the HTTP rewrite module requires the PCRE library.

    这个问题是要解决: yum -y install pcre-devel 然后在yum的时候发现出错.问题是我的linux不能上网. 这个问题搞得烦死了.和主机能ping.但是就是不能上网: ping ...