题解:P3343 [ZJOI2015] 地震后的幻想乡
简单题,速溶了。
首先发现题面里存在一个大大的提示,那么我们就从提示入手来做。容易发现我们只关心最后添加的一条边在
设
然后这个形式可以拆,另设
现在我们要求
然后现在就变成了计数问题。也就是我们要算添加
其中
复杂度
#include<bits/stdc++.h>
#define int long long
using namespace std;
#define lowbit(i) (i&(-i))
int n,m,x[1025],y[1025],C[1025][1025],h[1025],f[1025][1025][2];
double ans;
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cin>>n>>m;
C[0][0]=1;
for(int i=1;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];
}
for(int i=1;i<=m;i++) cin>>x[i]>>y[i],x[i]--,y[i]--;
for(int s=0;s<(1<<n);s++) for(int i=1;i<=m;i++) if(s&(1<<x[i]) && s&(1<<y[i])) h[s]++;
for(int s=1;s<(1<<n);s++){
for(int t=s;t;t=(t-1)&s) if(lowbit(s)==lowbit(t)) for(int i=0;i<=h[t];i++) for(int j=0;j<=h[s^t];j++) f[s][i+j][0]+=f[t][i][1]*C[h[s^t]][j];
for(int i=0;i<=h[s];i++) f[s][i][1]=C[h[s]][i]-f[s][i][0];
}
for(int i=0;i<=m;i++) ans+=1.0*f[(1<<n)-1][i][1]/C[m][i];
ans/=(m+1);
ans=1-ans;
printf("%.6lf",ans);
return 0;
}