bzoj 2878 [Noi2012]迷失游乐园——树上的期望dp
生活随笔
收集整理的這篇文章主要介紹了
bzoj 2878 [Noi2012]迷失游乐园——树上的期望dp
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
題目:https://www.lydsy.com/JudgeOnline/problem.php?id=2878
很好的樹上概率題的思路,就是分成up和down。
代碼中有眾多小細(xì)節(jié)。讓我棄療好幾天的致命小細(xì)節(jié)是dfs1里面那個(gè)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;//環(huán)上的點(diǎn)fa是0 up[cr]=d; //如果放在下面的式子里,就少加了d ——但是怎么會(huì)有!(son[fa]-1+f[fa])的情況呢? //fa只有一條邊的時(shí)候! 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]);} //環(huán)上的點(diǎn)不求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可能有多個(gè) 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; }?
轉(zhuǎn)載于:https://www.cnblogs.com/Narh/p/9243856.html
總結(jié)
以上是生活随笔為你收集整理的bzoj 2878 [Noi2012]迷失游乐园——树上的期望dp的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python之路--前端知识--Java
- 下一篇: jquery文件的引入