日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

bzoj 2878 [Noi2012]迷失游乐园——树上的期望dp

發布時間:2025/6/15 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 bzoj 2878 [Noi2012]迷失游乐园——树上的期望dp 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目:https://www.lydsy.com/JudgeOnline/problem.php?id=2878

很好的樹上概率題的思路,就是分成up和down。

代碼中有眾多小細節。讓我棄療好幾天的致命小細節是dfs1里面那個sum要定義成double的!……

#include<iostream> #include<cstdio> #include<cstring> #define db double using namespace std; const int N=1e5+5; int n,m,head[N],xnt,f[N],son[N],stack[N],top; db down[N],up[N]; bool vis[N],in[N],flag; struct Edge{int next,to,w;Edge(int n=0,int t=0,int w=0):next(n),to(t),w(w) {} }edge[N<<1]; void add(int x,int y,int z) {edge[++xnt]=Edge(head[x],y,z);head[x]=xnt;edge[++xnt]=Edge(head[y],x,z);head[y]=xnt; } void dfs1(int cr,int fa) {double sum=0;//doublefor(int i=head[cr],v;i;i=edge[i].next)if((v=edge[i].to)!=fa&&!in[v]){son[cr]++;dfs1(v,cr);sum+=down[v]+edge[i].w;//+edge[i].w!! }if(son[cr])down[cr]=sum/son[cr]; } void dfs2(int cr,int fa,int d) {if(fa)//判斷if(fa)!! {f[cr]=1;//環上的點fa是0 up[cr]=d; //如果放在下面的式子里,就少加了d ——但是怎么會有!(son[fa]-1+f[fa])的情況呢? //fa只有一條邊的時候! if(son[fa]-1+f[fa])up[cr]+=(down[fa]*son[fa]-d-down[cr]+up[fa]*f[fa])/(son[fa]-1+f[fa]); // printf("cr=%d up=%.5lf(upfa=%.5lf)\n",cr,up[cr],up[fa]);} //環上的點不求up,已在solve2里求過 for(int i=head[cr],v;i;i=edge[i].next)if((v=edge[i].to)!=fa&&!in[v])dfs2(v,cr,edge[i].w); } void tarjan(int cr,int fa) {stack[++top]=cr;vis[cr]=1;for(int i=head[cr],v;i;i=edge[i].next)if((v=edge[i].to)!=fa){if(vis[v]){while(stack[top]!=v)in[stack[top--]]=1;//!=v不是!=cr in[stack[top--]]=1;flag=1;return;}else tarjan(v,cr);if(flag)return;}top--;/ } void solve(int root,int cr,int fa,double g,int d)/////自己的寫法,判cr!=root!! {for(int i=head[cr],v;i;i=edge[i].next)if(in[v=edge[i].to]&&v!=fa){if(v==root){up[root]+=g*(down[cr]+d);// // printf("root=%d cr=%d up=%.5lf(down[cr]=%.5lf g=%.5lf)\n",root,cr,up[root],down[cr],g);return;}if(cr!=root)up[root]+=g*(down[cr]+d)*son[cr]/(son[cr]+1);//先+d再乘son[cr] // printf("root=%d cr=%d up=%.5lf(down[cr]=%.5lf son[cr]=%d g=%.5lf)\n",root,cr,up[root],down[cr],son[cr],g);if(cr==root)solve(root,v,cr,g/2,d+edge[i].w); //son可能有多個 else solve(root,v,cr,g/(son[cr]+1),d+edge[i].w);} } int main() {scanf("%d%d",&n,&m);int x,y,z;if(n==1){printf("0.00000");return 0;}for(int i=1;i<=m;i++){scanf("%d%d%d",&x,&y,&z);add(x,y,z);}if(m==n-1)dfs1(1,0),dfs2(1,0,0);else{tarjan(1,0);for(int i=1;i<=n;i++)if(in[i])dfs1(i,0);for(int i=1;i<=n;i++)if(in[i])solve(i,i,0,1,0);///!!!!!!!!for(int i=1;i<=n;i++)if(in[i])f[i]=2,dfs2(i,0,0);} // for(int i=1;i<=n;i++)printf("i=%d up=%.5lf down=%.5lf\n",i,up[i],down[i]);double sum=0;for(int i=1;i<=n;i++)sum+=(down[i]*son[i]+up[i]*f[i])/(son[i]+f[i]);printf("%.5lf",sum/n);return 0; }

?

轉載于:https://www.cnblogs.com/Narh/p/9243856.html

總結

以上是生活随笔為你收集整理的bzoj 2878 [Noi2012]迷失游乐园——树上的期望dp的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。