1. 程式人生 > >題解-ZJOI2015地震後的幻想鄉

題解-ZJOI2015地震後的幻想鄉

最小生成樹 typename ons bit spl 可能 簡述 連續 ++i

Problem

bzoj & 洛谷

題意簡述:給定一個\(n\)\(n\leq 10\))個點\(m\)條邊的無向圖,每條邊的權值為一個\(0\)\(1\)之間的連續隨機變量,求圖的最小生成樹中最大邊的期望權值

Solution

\(m\)個範圍\([0,1]\)之間的隨機變量中,第\(i\)大的值期望為\(\frac i{m+1}\)(這個式子我只會證最大值期望為\(\frac m{m+1}\),但不會證第\(i\)大的期望,如果有哪位神犇會證,請賜教)

有了這個東西,再考慮到原題是要求聯通即可,發現\(kruskal\)算法正好符合

將邊排序後加入,若加入到第\(i\)條邊時整張圖連通,則答案為\(\frac i{m+1}\)

;若期望第\(i‘\)次連通整張圖,則答案為\(\frac {i‘}{m+1}\)

\(f[S][i]\)表示用了\(i\)條邊不能使\(S\)聯通的方案數,\(g[S][i]\)表示用了\(i\)條邊能使\(S\)聯通的方案數,\(C[S]\)表示點集\(S\)內部道路數量

\[f[S][j]=\sum g[s][i]\cdot \binom {C[S-s]}{j-i}\]

\[g[S][j]=\binom {C[S]}i-f[S][j]\]

考慮到若第\(i\)條邊加入後仍未連通,則會對後面都造成影響(類似整數期望公式的一種統計方法)

\[Ans=\frac 1{m+1}\sum_{i=0}^m\frac {f[A][i]}{\binom {C[A]}{i}}\]

最後記得在枚舉集合的時候要定下一個點強制選擇,否則可能會拓撲序紊亂(代碼裏的做法就是\(S+=2\)而不是\(++S\),這樣枚舉的集合必定含有\(1\)號節點)

Code

#include <bits/stdc++.h>
typedef long long ll;
#define rg register

template <typename _Tp> inline _Tp read(_Tp&x){
    char c11=getchar(),ob=0;x=0;
    while(c11^‘-‘&&!isdigit(c11))c11=getchar();if(c11==‘-‘)ob=1,c11=getchar();
    while(isdigit(c11))x=x*10+c11-‘0‘,c11=getchar();if(ob)x=-x;return x;
}

const int N=11,M=60,MS=1<<N;
ll c[M][M],C[MS],f[MS][M],g[MS][M];
int n,m,A,bin[N];

void init();void work();void print();
int main(){init();work();print();return 0;}

void work(){
    for(rg int S=1;S<bin[n];S+=2)
    for(rg int j=0;j<=C[A];++j){
        for(rg int s=(S-1)&S;s;s=(s-1)&S)
        for(rg int i=0;i<=j;++i)
            f[S][j]+=g[s][i]*c[C[S-s]][j-i];
        g[S][j]=c[C[S]][j]-f[S][j];
    }
}

void print(){
    double ans(0.0);
    for(rg int i=0;i<=C[A];++i)
        ans+=1.0*f[A][i]/c[C[A]][i];
    printf("%.6lf\n",ans/(C[A]+1));
}

void init(){
    read(n),read(m);A=(1<<n)-1;
    int x,y;bin[0]=1;
    for(rg int i=1;i<=n;++i)bin[i]=bin[i-1]<<1;
    for(rg int i=0;i<=m;++i){
        c[i][0]=1;
        for(int j=1;j<=i;++j)
            c[i][j]=c[i-1][j-1]+c[i-1][j];
    }
    while(m--){
        read(x),read(y);--x,--y;
        for(rg int S=1;S<bin[n];++S)
            if( S&bin[x] and S&bin[y] )
                ++C[S];
    }
}

題解-ZJOI2015地震後的幻想鄉