SOL:不会积分的我瑟瑟发抖。
所以我选择状压DP。
我们有以下一个dp状态:
f[S][i],S表示点集,i表示这个点集向外联了i条边。
那么答案就是f[(1<<n)-1][0]了,那么让我们来考虑怎么转移。
。。。我口胡不下去了。
我们来考虑数学方法。
我们设答案是 EX,那么我们有以下数学推导:
(不会打数学公式,只好手写再拍照上传了)
就酱紫。
我的代码丑,给你们看看大佬的代码:
#include<bits/stdc++.h>
#define N 11
#define M 57
#define sight(c) ('0'<=c&&c<='9')
int n,m,x,y,lim;
bool vis[<<N][M];int T[<<N][<<N];double _f[<<N][M];
inline void read(int &x){
static char c;
for (c=getchar();!sight(c);c=getchar());
for (x=;sight(c);c=getchar()) x=x*+c-;
}
double f(int S, int t) {
if (S==) return ;
if (vis[S][t]) return _f[S][t];
vis[S][t]=true;
double &ans=(_f[S][t]=.);
for (int S2=(S-)&S; S2^S; S2=(S2-)&S) if (S2&) {
ans+=1.0/(t+T[S2][S&~S2]+);
ans-=f(S2,t+T[S2][S&~S2]);
}
return ans;
}
int main() {
read(n); read(m); lim=<<n;
while (m--) {
read(x); read(y);x--,y--;
for (int S1=;S1<lim;++S1) if ((S1>>x) & )
for (int S2=;S2<lim;++S2) if ((S2>>y) & )
++T[S2][S1],++T[S1][S2];
}
printf("%.6lf\n", f(lim-,));
return ;
}