這題訓(xùn)練賽時沒搞出來,我當(dāng)時從正面考慮,發(fā)現(xiàn)會有很多種情況
看了PKKJ的wiki  發(fā)現(xiàn)從反面考慮很好!!

/*
    題意:一個n個點(diǎn)的圖,任意兩點(diǎn)間有邊的概率為p  問該圖連通的概率
    設(shè)n個點(diǎn)連通的概率為dp[n],從不連通來考慮,_dp[n]=1-dp[n]

    對于編號為1的點(diǎn),它在其中的一個連通塊,枚舉該塊的大小 1n-1
    則該塊的k條邊必須與其余點(diǎn)的(n-k)條邊都不能連通
              n-1
    則_dp[n] = ∑ C[n-1,k-1]*dp[k]*(1-p)^(k*(n-k))
              k=1
    則dp[n]=1-_dp[n]

    最初,我是考慮最后怎么連通的情況,即點(diǎn)n是如何與其他塊連起來的,發(fā)現(xiàn)情況復(fù)雜:
    點(diǎn)n與大小為n-1的一個連通塊連起來
    點(diǎn)n作為中間點(diǎn)連接兩個塊
    點(diǎn)n作為中間點(diǎn)連接三個塊
    
    其實(shí)這樣子,就應(yīng)該要想到從反面來考慮!!考慮不連通
    要不連通,只需考慮某一個特殊的塊被獨(dú)立開來,而其他塊不管他連不連通
*/

#include
<cstdio>
#include
<cmath>

double dp[30];
int C[30][30];

void init()
{
    
for(int i=0;i<30;i++)
        C[i][
0]=C[i][i]=1;
    
for(int i=2;i<30;i++)
        
for(int j=1;j<i;j++)
            C[i][j]
=C[i-1][j]+C[i-1][j-1];
}


int main()
{
    init();
    
int n;
    
double p;
    
while(~scanf("%d%lf",&n,&p))
    
{
        dp[
1]=1.0;
        
//_dp[n] = ∑C[n-1,k-1]*dp[k]*(1-p)^(k*(n-k))
        
//dp[n]=1-_dp[n];
        for(int nn=2;nn<=n;nn++)
        
{
            
double ans = 0.0;
            
for(int k=1;k<nn;k++)
                ans
+=C[nn-1][k-1]*dp[k]*pow(1-p,k*(nn-k)+0.0);
            dp[nn]
=1-ans;
        }

        printf(
"%.8f\n",dp[n]);
    }

    
return 0;
}