JZOJ4890. 【NOIP2016提高A组集训第14场11.12】随机游走
来源:互联网 发布:golang http handler 编辑:程序博客网 时间:2024/06/05 03:41
Description
YJC最近在学习图的有关知识。今天,他遇到了这么一个概念:随机游走。随机游走指每次从相邻的点中随机选一个走过去,重复这样的过程若干次。YJC很聪明,他很快就学会了怎么跑随机游走。为了检验自己是不是欧洲人,他决定选一棵树,每条边边权为1,选一对点s和t,从s开始随机游走,走到t就停下,看看要走多长时间。但是在走了10000000步之后,仍然没有走到t。YJC坚信自己是欧洲人,他认为是因为他选的s和t不好,即从s走到t的期望距离太长了。于是他提出了这么一个问题:给一棵n个点的树,问所有点对(i,j)(1≤i,j≤n)中,从i走到j的期望距离的最大值是多少。YJC发现他不会做了,于是他来问你这个问题的答案。
Solution
今天在考场上想的已经有点接近正解,但在处理方式上处理不好,后来才发现正解太强了。
我们设f[i]表示第i个点往上走到自己父亲的期望步数,那么f[x]=∑y∈son[x]f[y]+f[x]+1|son[x]|+1+1|son[x]|+1 ,(∑y∈son[x]f[y]+f[x]+1|son[x]|+1 表示x先走到x的儿子后再走回x)化简得f[x]=|son[x]|+1+∑y∈son[x]f[y] 。我们设e(i,j)表示j的父亲i往下走到j的期望步数。那么e(x,y)=∑z∈son[x]1+f[z]+e(x,y)|son[x]|+1+1|son[x]|+1+e(fa[x],x)+1+e(x,y)|son[x]|+1 。解释一下:∑z∈son[x]1+f[z]+e(x,y)|son[x]|+1 表示x走到x别的儿子再走回x,最后走到y;e(fa[x],x)+1+e(x,y)|son[x]|+1 表示x走到自己的父亲后再走下来到x;1|son[x]|+1 表示x一步走到y。化简得e(x,y)=∑z∈son[x]f[z]+e(fa[x],x)+|son[x]|+1 。然后我们记g[y]=e(x,y)。
最后我们设f[x][0..1]分别表示从下往上走到x和x往下走的最大值,做一下树形dp取最大值即可。
Code
#include<iostream>#include<cmath>#include<cstring>#include<cstdio>#include<algorithm>#define db doubleusing namespace std;const int maxn=200005;int first[maxn],last[maxn],next[maxn],e[maxn],g[maxn],size[maxn],f[maxn][2];int n,i,t,j,k,l,num,x,y,ans;db ans1;void lian(int x,int y){ last[++num]=y;next[num]=first[x];first[x]=num;}void dg(int x,int y){ int t; e[x]=size[x]; for (t=first[x];t;t=next[t]){ if (last[t]==y) continue; dg(last[t],x); e[x]+=e[last[t]]; }}void dg1(int x,int y){ int t; for (t=first[x];t;t=next[t]){ if (last[t]==y) continue; g[last[t]]=e[x]-e[last[t]]+g[x]; dg1(last[t],x); }}void dg2(int x,int y){ int t,p,q,p1,q1;p=q=p1=q1=0; for (t=first[x];t;t=next[t]){ if (last[t]==y) continue; dg2(last[t],x); f[x][0]=max(f[x][0],f[last[t]][0]+g[last[t]]); f[x][1]=max(f[x][1],f[last[t]][1]+e[last[t]]); if (f[last[t]][0]+g[last[t]]>f[p][0]+g[p] || !p) p1=p,p=last[t]; else if (f[last[t]][0]+g[last[t]]>f[p1][0]+g[p1] || !p1) p1=last[t]; if (f[last[t]][1]+e[last[t]]>f[q][1]+e[q] || !q) q1=q,q=last[t]; else if (f[last[t]][1]+e[last[t]]>f[q1][1]+e[q1] || !q1) q1=last[t]; } if (p!=q) ans=max(ans,f[p][0]+g[p]+f[q][1]+e[q]); else ans=max(ans,max(f[p][0]+f[q1][1]+g[p]+e[q1],f[p1][0]+g[p1]+f[q][1]+e[q]));}int main(){ freopen("rw.in","r",stdin);freopen("rw.out","w",stdout); scanf("%d",&n); for (i=1;i<n;i++) scanf("%d%d",&x,&y),lian(x,y),lian(y,x),size[x]++,size[y]++; dg(1,0); dg1(1,0); dg2(1,0); ans1=ans; printf("%.5lf\n",ans1);}
1 0
- JZOJ4890. 【NOIP2016提高A组集训第14场11.12】随机游走
- 【JZOJ4890】【NOIP2016提高A组集训第14场11.12】随机游走
- 4890. 【NOIP2016提高A组集训第14场11.12】随机游走 (2017.10B组)
- 【NOIP2016提高A组集训第14场11.12】随机游走
- jzoj 4890. 【NOIP2016提高A组集训第14场11.12】随机游走 树上期望dp
- 【NOIP2016提高A组集训第14场11.12】随机游走
- 【NOIP2016提高A组集训第14场11.12】随机游走
- 【NOIP2016提高A组集训第14场11.12】随机游走——期望+树形DP
- NOIP2016提高A组集训第14场11.12 总结
- 最近公共祖先 【NOIP2016提高A组集训第14场11.12】
- 最长公共回文子序列 【NOIP2016提高A组集训第14场11.12】
- 【NOIP2016提高A组集训第14场11.12】最近公共祖先
- 【NOIP2016提高A组集训第14场11.12】最长公共回文子序列
- 【JZOJ4888】【NOIP2016提高A组集训第14场11.12】最近公共祖先
- 【NOIP2016提高A组集训第14场11.12】最近公共祖先
- JZOJ4888【NOIP2016提高A组集训第14场11.12】最近公共祖先
- 【JZOJ4889】【NOIP2016提高A组集训第14场11.12】最长公共回文子序列
- 【NOIP2016提高A组集训第3场10.31】方程式
- grails连接各个数据库
- Linux简单介绍
- 对 (function($){ })(jQuery); 的理解
- GStreamer基础教程翻译-及原文地址,看懂后GStreamer就快速入门了
- 步骤编程法简介
- JZOJ4890. 【NOIP2016提高A组集训第14场11.12】随机游走
- Java多线程
- 11.10
- kali persistence encryted!
- 顺序表 C++
- 告别软考——希望再也不“见”
- 正则表达式 学习
- HDU1238 字符暴搜
- 1202: [HNOI2005]狡猾的商人