【NOIP2016提高A組集訓第14場11.12】隨機遊走
阿新 • • 發佈:2018-05-21
出發 這樣的 提高 AI pac 答案 main 發現 next
\[G[i]=G[k]+\sum{F[l]}+d[k]\]
題目
YJC最近在學習圖的有關知識。今天,他遇到了這麽一個概念:隨機遊走。隨機遊走指每次從相鄰的點中隨機選一個走過去,重復這樣的過程若幹次。YJC很聰明,他很快就學會了怎麽跑隨機遊走。為了檢驗自己是不是歐洲人,他決定選一棵樹,每條邊邊權為1,選一對點s和t,從s開始隨機遊走,走到t就停下,看看要走多長時間。但是在走了10000000步之後,仍然沒有走到t。YJC堅信自己是歐洲人,他認為是因為他選的s和t不好,即從s走到t的期望距離太長了。於是他提出了這麽一個問題:給一棵n個點的樹,問所有點對(i,j)(1≤i,j≤n)中,從i走到j的期望距離的最大值是多少。YJC發現他不會做了,於是他來問你這個問題的答案。
分析
套路:
首先知道期望是可以累加的,即i通過j去到k的期望,等於i去到j的期望加j去到k的期望。
所以令d[i]表示i的出度,F[i]表示從i到i的父親的期望,G[i]表示i的父親到i的期望,j表示i其中任意一個兒子,k表示i的父親,l表示k其中任意一個兒子,e表示k的父親。
很容易推出:
\[F[i]=\dfrac{1}{d[i]}+\dfrac{1}{d[i]}\sum(1+F[j]+F[i])\]
\[G[i]=\dfrac{1}{d[k]}+\dfrac{1}{d[k]}(1+G[k]+G[i])+\dfrac{1}{d[k]}\sum(1+F[l]+G[i])\]
簡化後得
\[F[i]=\sum{F[j]}+d[i]\]
\[G[i]=G[k]+\sum{F[l]}+d[k]\]
枚舉(i,j)的lca,
記錄在以lca為根的子樹中,
從lca出發,和到達lca的最大期望值,
為了防止兩個最大值的lca不是枚舉了lca,記錄枚舉兒子中的最大值,
取最大次大值比較。
#include <cmath> #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <queue> const int maxlongint=2147483647; const int mo=1000000007; const int N=100005; using namespace std; int f[N],g[N]; int n,m,next[N*3],last[N*3],to[N*3],d[N],tot,deep[N],mx[N*2][8],ans; int bj(int x,int y) { next[++tot]=last[x]; last[x]=tot; to[tot]=y; } int dg(int x,int fa) { f[x]=d[x]; for(int i=last[x];i;i=next[i]) { int j=to[i]; if(j!=fa) { deep[j]=deep[x]+1; dg(j,x); f[x]+=f[j]; } } } int dg1(int x,int fa) { int sum1f=0; for(int i=last[x];i;i=next[i]) { int j=to[i]; if(j!=fa) { g[j]+=g[x]+d[x]; sum1f+=f[j]; } } for(int i=last[x];i;i=next[i]) { int j=to[i]; if(j!=fa) { g[j]+=sum1f-f[j]; dg1(j,x); } } } int dg2(int x,int fa) { for(int i=last[x];i;i=next[i]) { int j=to[i]; if(j!=fa) { dg2(j,x); if(mx[j][0]+f[j]>=mx[x][0]) { mx[x][1]=mx[x][0]; mx[x][0]=mx[j][0]+f[j]; mx[x][5]=mx[x][4]; mx[x][4]=j; } else if(mx[j][0]+f[j]>mx[x][1]) { mx[x][1]=mx[j][0]+f[j]; mx[x][5]=j; } if(mx[j][2]+g[j]>=mx[x][2]) { mx[x][3]=mx[x][2]; mx[x][2]=mx[j][2]+g[j]; mx[x][7]=mx[x][6]; mx[x][6]=j; } else if(mx[j][2]+g[j]>mx[x][3]) { mx[x][3]=mx[j][2]+g[j]; mx[x][7]=j; } } } if(mx[x][4]!=mx[x][6]) { if(mx[x][0]+mx[x][2]>ans) ans=mx[x][0]+mx[x][2]; } if(mx[x][5]!=mx[x][6]) { if(mx[x][1]+mx[x][2]>ans) ans=mx[x][1]+mx[x][2]; } if(mx[x][4]!=mx[x][7]) { if(mx[x][0]+mx[x][3]>ans) ans=mx[x][0]+mx[x][3]; } } int main() { scanf("%d",&n); for(int i=1;i<=n-1;i++) { int x,y; scanf("%d%d",&x,&y); d[x]++; d[y]++; bj(x,y); bj(y,x); } deep[1]=1; dg(1,0); dg1(1,0); dg2(1,0); printf("%d.00000",ans); }
【NOIP2016提高A組集訓第14場11.12】隨機遊走