博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
树形dp聪聪和可可(vijos1675)
阅读量:4992 次
发布时间:2019-06-12

本文共 1526 字,大约阅读时间需要 5 分钟。

题目链接:

题解:完全不会写有关期望的问题,怎么办嘞。。。。

首先因为每次聪聪都会往离可可最短的路走,我们先用求出p[i][j](其实就是拓扑。。。)来表示从i节点到j节点走最短路到达的第一个节点。

然后每次都dfs聪聪下一步可能会走的节点,只要有哪一层p[i][j]==j或p[p[i][j]][j]==j(因为聪聪能走两步)就返回1,可可一定会被聪聪抓到,用now表示p[p[i][j]][j];

f[i][j]=sum(f[now][j])/(可可可以走的方案数,即出边的数量加1)+1(为什么要在最后加1呢?因为我们首先需要走到now这个节点);

下面是具体程序

#include
#include
#include
#include
using namespace std;struct ding{ int to,next;}edge[5000];int n,head[2000],deg[2000],cnt,dis[2000],p[2000][2000];double f[2000][2000];void add(int u,int v) { edge[++cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt; deg[u]++;//用deg[i]来储存出边}void bfs(int s){//我们假设以当前节点为根,因为这是一棵树,所以保证先更新的点一定是后更新的点的父节点,即父节点的值若已被更新就不会因后面的改变而改变 queue
q; q.push(s); memset(dis,-1,sizeof dis); dis[s]=0; while (!q.empty()) { int now=q.front(),tmp=p[s][now]; q.pop(); for (int i=head[now];i;i=edge[i].next) { int y=edge[i].to; if ((dis[y]==-1)||((dis[now]+1==dis[y])&&(tmp
0) return f[s][t]; if (s==t) return 0; if ((p[s][t]==t)||(now==t)) return f[s][t]=1; double sum=dp(now,t); for (int i=head[t];i;i=edge[i].next) sum+=dp(now,edge[i].to); return f[s][t]=sum/(deg[t]+1)+1;}int main(){ int m,a,b,x,y; scanf("%d%d%d%d",&n,&m,&a,&b); for (int i=1;i<=m;i++) { scanf("%d%d",&x,&y); add(x,y);add(y,x);//正向反向都要加 } for (int i=1;i<=n;i++) bfs(i); //处理出i这个点到其他店的最短路 printf("%0.3lf\n",dp(a,b)); return 0;}

 

转载于:https://www.cnblogs.com/2014nhc/p/6625540.html

你可能感兴趣的文章
集合遍历过程iterator, 添加删除元素报异常
查看>>
echarts一些笔记
查看>>
最长上升子序列
查看>>
Java-面向对象
查看>>
salesforce 零基础学习(四十四)实现checkbox列表简单过滤功能
查看>>
Android 异步下载
查看>>
c# 中 利用 CookieContainer 对 Cookie 进行序列化和反序列化校验
查看>>
Leetcode 743. Closest Leaf in a Binary Tree
查看>>
如何用Java实现反转排序
查看>>
自己动手写字符串库函数 一(C语言实现) 分类: C语言学习 ...
查看>>
说说接口封装
查看>>
Linux Supervisor的安装与使用入门---SuSE
查看>>
C#将Word转换成PDF方法总结(基于Office和WPS两种方案)
查看>>
oracle查锁表
查看>>
PHP SSH2 不支持 IdentityFile
查看>>
eclipse 僵死/假死 问题排查及解决
查看>>
番茄时间
查看>>
四位计算机的原理及其实现【转】
查看>>
mediawiki简易安装文档
查看>>
Ubuntu server 命令备忘
查看>>