举个栗子
E(2,3,3)=p1*E(2,3,3)+p2*E(2,6)+p3*E(3,5)+1
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<map>
#include<vector>
using namespace std;
typedef vector<int> data;
inline char nc()
{
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x)
{
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
const int N=35;
int fat[N],size[N];
inline int Fat(int u) { return u==fat[u]?u:fat[u]=Fat(fat[u]); }
int n,m,all;
map<data,double> f;
double dp(data v){
if (f.count(v)) return f[v];
if (v.size()==1) { return f[v]=0; }
double ret=0; int cnt=0;
for (int i=0;i<(signed)v.size();i++) cnt+=v[i]*(v[i]-1)/2;
ret=(double)all/(all-cnt);
for (int i=0;i<(signed)v.size();i++)
for (int j=0;j<i;j++){
data nxt=v;
nxt[j]+=nxt[i],swap(nxt[i],nxt[v.size()-1]);
nxt.pop_back(),sort(nxt.begin(),nxt.end());
ret+=(double)v[i]*v[j]/(all-cnt)*dp(nxt);
}
return f[v]=ret;
}
int main()
{
data org; int x,y;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(n); read(m); all=n*(n-1)/2;
for (int i=1;i<=n;i++) fat[i]=i,size[i]=1;
for (int i=1;i<=m;i++){
read(x); read(y); x=Fat(x),y=Fat(y);
if (x!=y)
fat[x]=y,size[y]+=size[x];
}
for (int i=1;i<=n;i++) if (fat[i]==i) org.push_back(size[i]);
sort(org.begin(),org.end());
printf("%.6lf\n",dp(org));
return 0;
}