zoukankan      html  css  js  c++  java
  • CF235D

    题意:求基环树随机点分治次数期望

    首先,这道题的本质是给分治中心随机排列。
    考虑分治中心x与y连通的概率,若x到y是一条链,就要求x到y上的所有点,在x之后被删除。
    把这些概率加到一起就是答案。
    如果这条链包含的点数为a,容易证出此时是1/a。
    (共有(n!)种情况,满足条件的有(frac{n!}{a})种)

    如果x到y的路径上经过环,设除去环的部分点数为a,环的两部分点数分别为b和c。
    只要除去环上任意一侧的点,都在x之前被删除即可,这部分为(frac{1}{a+b}),加上(frac{1}{a+c}),但是,还有所有的点都在x之前被删除的情况,这种情况会被算两次,需要减掉,就是再减去(frac{1}{a+b+c})
    (O(n^2))枚举点对进行计算即可。

    代码:

    #include <stdio.h>
    int fr[3010],ne[6010],v[6010],bs=0;
    void addb(int a,int b)
    {
    	v[bs]=b;
    	ne[bs]=fr[a];
    	fr[a]=bs++;
    }
    int bk[3010],sd[3010],hu[3010],fa[3010],sl=0;
    void dfs1(int u,int f)
    {
    	bk[u]=1;fa[u]=f;
    	sd[u]=sd[f]+1;
    	for(int i=fr[u];i!=-1;i=ne[i])
    	{
    		if(v[i]==f)continue;
    		if(bk[v[i]])
    		{
    			if(sd[v[i]]<sd[u])
    			{
    				int t=u;
    				while(1)
    				{
    					hu[sl++]=t;
    					if(t==v[i])break;
    					t=fa[t];
    				}
    			}
    		}
    		else
    			dfs1(v[i],u);
    	}
    }
    int hd[3010],ro[3010],lc[3010][3010],wz[3010];
    void dfs2(int u,int f,int rt)
    {
    	fa[u]=f;ro[u]=rt;
    	sd[u]=sd[f]+1;
    	for(int i=fr[u];i!=-1;i=ne[i])
    	{
    		if(v[i]==f||hd[v[i]])
    			continue;
    		dfs2(v[i],u,rt);
    	}
    }
    int dfs3(int a,int b)
    {
    	if(a==b)
    		return lc[a][b]=a;
    	if(lc[a][b])
    		return lc[a][b];
    	if(sd[a]>sd[b])
    		lc[a][b]=dfs3(fa[a],b);
    	else
    		lc[a][b]=dfs3(a,fa[b]);
    	return lc[a][b];
    }
    int getdis(int a,int b)
    {
    	int l=dfs3(a,b);
    	return sd[a]+sd[b]-sd[l]*2+1;
    }
    int main()
    {
    	int n;
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    		fr[i]=-1;
    	for(int i=0;i<n;i++)
    	{
    		int a,b;
    		scanf("%d%d",&a,&b);
    		a+=1;b+=1;
    		addb(a,b);addb(b,a);
    	}
    	dfs1(1,0);
    	for(int i=0;i<sl;i++)
    	{
    		hd[hu[i]]=1;
    		wz[hu[i]]=i;
    	}
    	for(int i=0;i<sl;i++)
    		dfs2(hu[i],0,hu[i]);
    	double ans=0;
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=1;j<=n;j++)
    		{
    			if(ro[i]==ro[j])
    				ans+=1.0/getdis(i,j);
    			else
    			{
    				int a=sd[i]+sd[j];
    				int b=wz[ro[i]]-wz[ro[j]];
    				if(b<0)b=-b;
    				b-=1;int c=sl-2-b;
    				ans+=1.0/(a+b);
    				ans+=1.0/(a+c);
    				ans-=1.0/(a+b+c);
    			}
    		}
    	}
    	printf("%.10lf",ans);
    	return 0;
    }
    
  • 相关阅读:
    nodejs express搭建一个网站整理
    nodejs http post 请求带参数
    express respond.send 和 end的区别
    .net程序员做的第一个安卓APP
    angularjs ui-grid如何动态设置行高
    错误处理(Operation Result)方法
    jquery validation yyyy-MM-dd格式日期在ie中无法验证通过
    PAT (Basic Level) Practise (中文)- 1010. 一元多项式求导 (25)
    PAT (Basic Level) Practise (中文)- 1007. 素数对猜想 (20)
    PAT (Basic Level) Practise (中文)- 1012. 数字分类 (20)
  • 原文地址:https://www.cnblogs.com/lnzwz/p/12863328.html
Copyright © 2011-2022 走看看