zoukankan      html  css  js  c++  java
  • 【LOJ #2136】「ZJOI2015」地震后的幻想乡(状压DP)

    传送门


    考虑对于一个边集S|S|
    如果刚好加入第ii条边的时候联通
    那么贡献就是Sm+1PSfrac{|S|}{m+1}*P_{|S|}

    PSP_{|S|}表示SS中的边恰好是最小的S|S|条的概率
    fs,if_{s,i}表示点集SS联通,连了ii条边的方案数
    gg为不连通的方案数
    那么有fs,i+gs,i=(Esi)Esf_{s,i}+g_{s,i}={E_{s}choose i},E_sSS中边数
    gg可以枚举标号最小的点所在的连通块dpdp

    那么ii条边恰好联通的概率就是gU,i1(EUi1)gU,i(EUi)frac{g_{U,i-1}}{{E_U}choose i-1}-frac{g_{U,i}}{{E_Uchoose i}}

    #include<bits/stdc++.h>
    using namespace std;
    #define cs const
    #define re register
    #define pb push_back
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define ll long long
    cs int RLEN=1<<20|1;
    inline char gc(){
    	static char ibuf[RLEN],*ib,*ob;
    	(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
    	return (ib==ob)?EOF:*ib++;
    }
    inline int read(){
    	char ch=gc();
    	int res=0;bool f=1;
    	while(!isdigit(ch))f^=ch=='-',ch=gc();
    	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
    	return f?res:-res;
    }
    template<class tp>inline void chemx(tp &a,tp b){a<b?a=b:0;}
    template<class tp>inline void chemn(tp &a,tp b){a>b?a=b:0;}
    cs int N=12,M=55,S=(1<<10)|5;
    int n,sta,m,E[S];
    ll f[S][M],g[S][M],c[M][M];
    pii e[M];
    inline int calc(int s){
    	int cnt=0;
    	for(int i=1;i<=m;i++)
    		if((s&(1<<(e[i].fi-1)))&&(s&(1<<(e[i].se-1))))cnt++;
    	return cnt;
    }
    inline int lowbit(int x){return x&(-x);}
    int main(){
    	#ifdef Stargazer
    	freopen("lx.cpp","r",stdin);
    	#endif
    	n=read(),m=read(),sta=1<<n;
    	for(int i=0;i<=m;i++){
    		c[i][0]=c[i][i]=1;
    		for(int j=1;j<i;j++)
    		c[i][j]=c[i-1][j]+c[i-1][j-1];
    	}
    	for(int i=1;i<=m;i++){
    		e[i].fi=read(),e[i].se=read();
    	}
    	for(int i=0;i<sta;i++)E[i]=calc(i);
    	for(int s=1;s<sta;s++){
    		int now=s-lowbit(s);
    		for(int i=0;i<=E[s];i++){
    			for(int sub=now;;sub=(sub-1)&now){
    				int in=s-sub;
    				for(int j=0;j<=E[in]&&j<=i;j++){
    					g[s][i]+=f[in][j]*c[E[s-in]][i-j];
    				}
    				if(!sub)break;
    			}
    			f[s][i]=c[E[s]][i]-g[s][i];
    		}
    	}
    	double res=0;
    	for(int i=1;i<=m;i++){
    		res+=1.0*i/(m+1)*(1.0*g[sta-1][i-1]/c[m][i-1]-1.0*g[sta-1][i]/c[m][i]);
    	}
    	printf("%.6lf",res);
    }
    
  • 相关阅读:
    Android Studio来了,是否准备抛弃Eclipse?
    Android Studio来了,是否准备抛弃Eclipse?
    文件名搜索神器Everything(201306更新)
    文件名搜索神器Everything(201306更新)
    可替代Windows任务管理器System Explorer
    log4j使用详解
    复平面和直角坐标系的思考
    芯片内电路和芯片外围电路
    复数的思考
    时不变的思考
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328366.html
Copyright © 2011-2022 走看看