zoukankan      html  css  js  c++  java
  • 【BZOJ2878】【NOI2012】—迷失游乐园(基环树期望dp)

    传送门

    考虑没有环的时候怎么做
    之前做过一次类似的简单题,只不过是有向图

    考虑无向图的时候记录一个sis_i表示ii向儿子走的期望长度,downidown_i表示向儿子走的长度之和
    downu=v=sonusv+vale,su=downusonudown_u=sum_{v=son_u}s_{v}+val_e,s_u=frac{down_u}{son_u}

    再一个upiup_i表示向父亲走的期望长度
    upu=downfasvvale+upfasonfa+valeup_u=frac{down_{fa}-s_v-val_e+up_{fa}}{son_fa}+val_e

    也就是向父亲的父亲走或者别的儿子走的可能之和

    现在有一个环,考虑怎么做

    由于环的节点很少,考虑暴力枚举环上每一个节点xx并往周围走计算期望长度ff

    fu=downu+fvsoni+1,vuf_u=frac{down_u+f_v}{son_i+1},v是u在环上的后继
    而对于当前枚举的节点xx处理一下分别向两边延伸的长度,就可以得到upxup_x

    对环上每一个节点这样计算一下upup并给子树统计一下就完了

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
    	char ch=getchar();
    	int res=0,f=1;
    	while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=getchar();
    	return res*f;
    }
    const int N=100005;
    int adj[N],nxt[N<<1],to[N<<1],val[N<<1],n,m,siz[N],in[N],cnt;
    double down[N],s[N],up[N];
    inline void addedge(int u,int v,int w){
    	nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v,val[cnt]=w,in[u]++;
    }
    namespace Tree{
    	inline void dfs1(int u,int f){
    		for(int e=adj[u];e;e=nxt[e]){
    			int v=to[e];
    			if(v==f)continue;
    			dfs1(v,u);
    			down[u]+=s[v]+val[e],siz[u]++;
    		}
    		if(siz[u])s[u]=down[u]/siz[u];
    	}
    	inline void dfs2(int u,int f){
    		for(int e=adj[u];e;e=nxt[e]){
    			int v=to[e];
    			if(v==f)continue;
    			if(u==1&&in[u]==1)up[v]=val[e];
    			else if(u==1)up[v]=(up[u]+down[u]-s[v]-val[e])/(siz[u]-1)+val[e];
    			else up[v]=(up[u]+down[u]-s[v]-val[e])/siz[u]+val[e];
    			dfs2(v,u);
    		}
    	}
    	inline void main(){
    		dfs1(1,0);
    		dfs2(1,0);
    		double res=(down[1]+up[1])/siz[1];
    		for(int i=2;i<=n;i++){
    			res+=(down[i]+up[i])/in[i];
    		}
    		printf("%.5lf",res/n);	
    	}
    }
    namespace Circle{
    	int pre[N],inc[N],dfn[N],tim;
    	void Findc(int u){
    		dfn[u]=++tim;
    		for(int e=adj[u];e;e=nxt[e]){
    			int v=to[e];
    			if(v==pre[u])continue;
    			if(!dfn[v])pre[v]=u,Findc(v);
    			else if(dfn[v]<dfn[u]){
    				for(int x=u;x!=v;x=pre[x])inc[x]=1;
    				inc[v]=1;return;
    			}
    		}
    	}
    	void dfs1(int u,int f){
    		for(int e=adj[u];e;e=nxt[e]){
    			int v=to[e];
    			if(v==f||inc[v])continue;
    			dfs1(v,u);
    			siz[u]++,down[u]+=s[v]+val[e];
    		}
    		if(siz[u])s[u]=down[u]/siz[u];
    	}
    	double around(int u,int fa,int des){
    		for(int e=adj[u];e;e=nxt[e]){
    			int v=to[e];
    			if(!inc[v]||v==fa)continue;
    			if(v==des)return s[u];
    			return (down[u]+around(v,u,des)+val[e])/(siz[u]+1);
    		}
    	}
    	inline void calc(int u){
    		for(int e=adj[u];e;e=nxt[e]){
    			int v=to[e];
    			if(!inc[v])continue;
    			up[u]+=around(v,u,u)+val[e];
    		}
    		up[u]/=2;
    	}
    	void dfs2(int u,int f){
    		for(int e=adj[u];e;e=nxt[e]){
    			int v=to[e];
    			if(v==f||inc[v])continue;
    			if(inc[u])up[v]=(up[u]*2+down[u]-s[v]-val[e])/(siz[u]+1)+val[e];
    			else up[v]=(up[u]+down[u]-s[v]-val[e])/siz[u]+val[e];
    			dfs2(v,u);
    		}
    	}
    	inline void main(){
    		Findc(1);double res=0;
    		for(int i=1;i<=n;i++)
    			if(inc[i])dfs1(i,0);
    		for(int i=1;i<=n;i++)
    			if(inc[i])calc(i);
    		for(int i=1;i<=n;i++)
    			if(inc[i])dfs2(i,0);
    		for(int i=1;i<=n;i++){
    			if(inc[i])res+=(down[i]+up[i]*2)/(in[i]);
    			else res+=(down[i]+up[i])/(in[i]);
    		}
    		printf("%.5lf",res/n);
    	}
    }
    int main(){
    	n=read(),m=read();
    	for(int i=1;i<=m;i++){
    		int u=read(),v=read(),w=read();
    		addedge(u,v,w),addedge(v,u,w);
    	}
    	if(m==n-1)Tree::main();
    	else Circle::main();
    }
    
  • 相关阅读:
    16款优秀的Vue UI组件库推荐
    通过论证:查询字段通常返回引用,该引用可以保证是原来的对象的状态的一部分。分析变量在内存中的变化过程。
    使用XtraReport的CalculatedFiled(计算字段)实现RDLC报表中表达式
    Task:取消异步计算限制操作 & 捕获任务中的异常
    webAPI 自动生成帮助文档
    live writer 博客测试
    c#基础 函数传值
    Google,真的要离我们而去吗?
    匹配中文字符的正则表达式: [/u4e00-/u9fa5]
    希尔排序的实现
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/11145585.html
Copyright © 2011-2022 走看看