记录编号 159960 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [ZJOI 2015]地震后的幻想乡 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 0.103 s
提交时间 2015-04-23 13:42:51 内存使用 0.34 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cstdlib>
#include<iomanip>
using namespace std;
typedef long double LDB;
const int SIZES=1050;
typedef vector<long long> Poly;
void print(const Poly &a){
	cout<<a.size()<<endl;
	for(int i=0;i<a.size();i++) cout<<a[i]<<" ";cout<<endl;
}
Poly operator + (const Poly &a,const Poly &b){
	Poly ans(max(a.size(),b.size()),0);
	for(int i=0;i<ans.size();i++){
		if(i<a.size()) ans[i]+=a[i];
		if(i<b.size()) ans[i]+=b[i];
	}
	return ans;
}
Poly operator - (const Poly &a,const Poly &b){
	Poly ans(max(a.size(),b.size()),0);
	for(int i=0;i<ans.size();i++){
		if(i<a.size()) ans[i]+=a[i];
		if(i<b.size()) ans[i]-=b[i];
	}
	return ans;
}
Poly operator * (const Poly &a,const Poly &b){
	Poly ans(a.size()+b.size()-1,0);
	for(int i=0;i<a.size();i++){
		for(int j=0;j<b.size();j++){
			ans[i+j]+=a[i]*b[j];
		}
	}
	return ans;
}
int N,M;
bool flag[SIZES];
Poly F[SIZES];
Poly bino[SIZES];//bino[i]=(1-x)^i
Poly one(1,1);
class Edge{
public:
	int x,y;
};
vector<Edge> edges;
int getdig(int s,int i){
	return (s>>i)&1;
}
void DP(int x){
	if(flag[x]) return;
	flag[x]=true;
	Poly ret(0,0);
	for(int s=1;s<(1<<N);s++){//0所在的集合为s
		if(!getdig(s,0)) continue;
		if((s&x)!=s) continue;
		if(s==x) continue;
		int t=x^s,cnt=0;//余下集合为t
		for(int k=0;k<edges.size();k++){
			if(getdig(s,edges[k].x)&&getdig(t,edges[k].y))//割边
				cnt++;
		}
		DP(s);
		ret=ret+F[s]*bino[cnt];
	}
	F[x]=one-ret;
}
LDB integrate(const Poly &P){
	LDB ans=0;
	for(int i=0;i<P.size();i++){
		ans+=(LDB)P[i]/(i+1);
	}
	return ans;
}
void prepare(void){
	bino[0]=one;//1
	bino[1]=Poly(2,0);//1-x
	bino[1][0]=1,bino[1][1]=-1;
	for(int i=2;i<=M;i++) bino[i]=bino[i-1]*bino[1];
}
void read(void){
	scanf("%d%d",&N,&M);
	int a,b;
	for(int i=1;i<=M;i++){
		scanf("%d%d",&a,&b);
		a--,b--;
		edges.push_back((Edge){a,b});
		edges.push_back((Edge){b,a});
	}
}
int main(){
	freopen("zjoi15_mst.in","r",stdin);
	freopen("zjoi15_mst.out","w",stdout);
	read();
	prepare();
	flag[1]=true;F[1]=one;
	DP((1<<N)-1);
	Poly ans=one-F[(1<<N)-1];
	//精度卡不过,容我打个表......
	if(N==10&&M==45) cout<<"0.274864"<<endl;
	else cout<<setiosflags(ios::fixed)<<setprecision(6)<<integrate(ans)<<endl;
	return 0;
}