版权声明:神的bolg... https://blog.csdn.net/Rose_max/article/details/86488610
Description
题解
感觉直接做也是可以的啊…只不过好像很麻烦
第一种边直接做了不用理…
现在要把2,3两种边拆开,让他变成第一种边做
第二种拆成两条不相关的 的边,显然单选任意一条边时候贡献与两条出现是相同的,只有两条边都计入完备匹配的时候概率会变成 ,所以可以加一条强行要让四个点连起来的边,概率
第三种类似上面,概率变成 即可
然后可以一个 表示 这个状态的点完备匹配的期望是什么
转移的话我们枚举编号最小的点是和谁匹配的然后去到下一个状态
记忆化搜一搜
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<ctime>
#include<map>
#include<bitset>
#include<set>
#define LL long long
#define mp(x,y) make_pair(x,y)
#define pll pair<long long,long long>
#define pii pair<int,int>
using namespace std;
inline int read()
{
int f=1,x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int stack[20];
inline void write(LL x)
{
if(x<0){putchar('-');x=-x;}
if(!x){putchar('0');return;}
int top=0;
while(x)stack[++top]=x%10,x/=10;
while(top)putchar(stack[top--]+'0');
}
inline void pr1(int x){write(x);putchar(' ');}
inline void pr2(LL x){write(x);putchar('\n');}
const LL mod=1e9+7;
const LL inv=500000004;
const LL inv1=250000002;
const int MAXMASK=(1<<15);
const int MAXM=305;
const int MAXN=20;
struct node{int x,y,u,v,next;LL ar;}a[MAXM];int len,last[MAXN];
void ins(int x,int y,int u,int v,LL ar)
{
len++;
a[len].x=x;a[len].y=y;a[len].u=u;a[len].v=v;a[len].next=last[x];last[x]=len;
a[len].ar=ar;
}
int bin[35],fac[MAXMASK],n,m;
map<int,LL> mp[MAXMASK],vis[MAXMASK];
int lowbit(int x){return fac[x&-x];}
void ad(LL &x,LL y){x+=y;if(x>=mod)x-=mod;}
LL dp(int u1,int u2)
{
if(!u1&&!u2)return 1;
if(vis[u1][u2])return mp[u1][u2];
vis[u1][u2]=1;
int x=lowbit(u1);LL ret=0;
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;if(u2&bin[y])
{
if(!a[k].u)ad(ret,(a[k].ar*dp(u1^bin[x],u2^bin[y])%mod+mod)%mod);
else if(((u1^bin[x])&bin[a[k].u])&&((u2^bin[y])&bin[a[k].v]))ad(ret,(a[k].ar*dp(u1^bin[x]^bin[a[k].u],u2^bin[y]^bin[a[k].v])%mod+mod)%mod);
}
}
return mp[u1][u2]=ret;
}
int main()
{
bin[1]=1;for(int i=2;i<=20;i++)bin[i]=bin[i-1]<<1;
for(int i=1;i<=15;i++)fac[bin[i]]=i;
n=read();m=read();
for(int i=1;i<=m;i++)
{
int opt=read(),u1=read(),u2=read();
if(opt)
{
int u3=read(),u4=read();
if(u1>u3)swap(u1,u3),swap(u2,u4);
ins(u1,u2,0,0,inv);ins(u3,u4,0,0,inv);
if(u1==u3||u2==u4)continue;
if(opt==1)ins(u1,u2,u3,u4,inv1);
else ins(u1,u2,u3,u4,-inv1);
}
else ins(u1,u2,0,0,inv);
}
pr2(dp(bin[n+1]-1,bin[n+1]-1)*bin[n+1]%mod);
return 0;
}