根据题意,题目中所求的即为所有\(n!\)种完美匹配的各自的出现概率之和再乘上\(2^n\)的值。

发现\(n\)很小,考虑状压\(DP\)。设\(f_{S,T}\)为左部图匹配情况为\(S\),右部图匹配情况为\(T\)的期望,可以得到转移为:

\[
f_{S,T}=\sum_{x \subseteqq S \land y \subseteqq T }f_{S \oplus x,T \oplus y} \times p_e

\]

其中\(x,y\)为边\(e\)的在两个部图的两个端点,\(p_e\)为这条边的出现概率,转移的含义为加上\(e\)这条边后\(x\)和\(y\)实现了匹配。

发现直接这样转移会算重,所以要事先固定一种转移顺序,可以是每次在\(S\)中去除最高位来转移,也就是从低位向高位转移,这样就保证不会算重了。

然后考虑如何解决每条边的出现概率,第一组边不用特殊考虑,概率为\(\frac{1}{2}\)。考虑是否可以把第二组和第三组边也转化为第一种的形式。可以先将第二组和第三组边的两条边都以概率为\(\frac{1}{2}\)加入,对于第二组边,这时两条边同时出现的概率为\(\frac{1}{4}\),不符合题目\(\frac{1}{2}\)的要求,因此再加入同时选这两条边的情况,概率为\(\frac{1}{4}\),对于第三组边,再加入同时选这两条边的情况,概率为\(-\frac{1}{4}\)。根据期望的线性性,发现这样处理是正确的,并且恰好符合了题目的要求。

第二组和第三组边中,若两条边有交集,即两条边为一个点连向另外两个点,此时是不用加上同时选这两条边的情况的,因为题目所求为完美匹配,一个点匹配两个点的情况是不存在的。

处理完边后,记忆化搜索来实现状压\(DP\)即可。

\(code:\)

#include<bits/stdc++.h>
#define maxs 70010
#define p 1000000007
#define inv2 500000004
#define inv4 250000002
#define sta(x) (1<<(x-1))
using namespace std;
typedef long long ll;
template<typename T> inline void read(T &x)
{
x=0;char c=getchar();bool flag=false;
while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
if(flag)x=-x;
}
int n,m,cnt;
map<int,ll> f[maxs];
struct node
{
ll s,t,v;
}e[maxs];
ll dp(int S,int T)
{
if(!S) return 1;
if(f[S].count(T)) return f[S][T];
for(int i=1;i<=cnt;++i)
{
ll s=e[i].s,t=e[i].t,v=e[i].v;
if((S|s)!=S||(T|t)!=T||S>=(s<<1)) continue;
f[S][T]=(f[S][T]+dp(S^s,T^t)*v%p)%p;
}
return f[S][T];
}
int main()
{
read(n),read(m);
for(int i=1;i<=m;++i)
{
int opt,x,y;
read(opt),read(x),read(y),e[++cnt]=(node){sta(x),sta(y),inv2};
if(opt)
{
read(x),read(y);
if(!((sta(x)&e[cnt].s)||(sta(y)&e[cnt].t)))
{
cnt++;
if(opt==1) e[cnt]=(node){sta(x)|e[cnt-1].s,sta(y)|e[cnt-1].t,inv4};
else e[cnt]=(node){sta(x)|e[cnt-1].s,sta(y)|e[cnt-1].t,p-inv4};
}
e[++cnt]=(node){sta(x),sta(y),inv2};
}
}
printf("%lld",dp((1<<n)-1,(1<<n)-1)*(1<<n)%p);
return 0;
}

题解 洛谷 P4547 【[THUWC2017]随机二分图】的更多相关文章

  1. P4547 [THUWC2017]随机二分图(状压,期望DP)

    期望好题. 发现 \(n\) 非常小,应该要想到状压的. 我们可以先只考虑 0 操作. 最难的还是状态: 我们用 \(S\) 表示左部点有哪些点已经有对应点, \(T\) 表示右部点有哪些点已经有对应 ...

  2. 【BZOJ2830/洛谷3830】随机树(动态规划)

    [BZOJ2830/洛谷3830]随机树(动态规划) 题面 洛谷 题解 先考虑第一问. 第一问的答案显然就是所有情况下所有点的深度的平均数. 考虑新加入的两个点,一定会删去某个叶子,然后新加入两个深度 ...

  3. [LOJ2290] [THUWC2017] 随机二分图

    题目链接 LOJ:https://loj.ac/problem/2290 洛谷:https://www.luogu.org/problemnew/show/P4547 Solution 首先考虑只有第 ...

  4. 题解 洛谷P5018【对称二叉树】(noip2018T4)

    \(noip2018\) \(T4\)题解 其实呢,我是觉得这题比\(T3\)水到不知道哪里去了 毕竟我比较菜,不大会\(dp\) 好了开始讲正事 这题其实考察的其实就是选手对D(大)F(法)S(师) ...

  5. 题解 洛谷 P3396 【哈希冲突】(根号分治)

    根号分治 前言 本题是一道讲解根号分治思想的论文题(然鹅我并没有找到论文),正 如论文中所说,根号算法--不仅是分块,根号分治利用的思想和分块像 似却又不同,某一篇洛谷日报中说过,分块算法实质上是一种 ...

  6. 题解-洛谷P5410 【模板】扩展 KMP(Z 函数)

    题面 洛谷P5410 [模板]扩展 KMP(Z 函数) 给定两个字符串 \(a,b\),要求出两个数组:\(b\) 的 \(z\) 函数数组 \(z\).\(b\) 与 \(a\) 的每一个后缀的 L ...

  7. 题解-洛谷P4229 某位歌姬的故事

    题面 洛谷P4229 某位歌姬的故事 \(T\) 组测试数据.有 \(n\) 个音节,每个音节 \(h_i\in[1,A]\),还有 \(m\) 个限制 \((l_i,r_i,g_i)\) 表示 \( ...

  8. 题解-洛谷P4724 【模板】三维凸包

    洛谷P4724 [模板]三维凸包 给出空间中 \(n\) 个点 \(p_i\),求凸包表面积. 数据范围:\(1\le n\le 2000\). 这篇题解因为是世界上最逊的人写的,所以也会有求凸包体积 ...

  9. 题解-洛谷P4859 已经没有什么好害怕的了

    洛谷P4859 已经没有什么好害怕的了 给定 \(n\) 和 \(k\),\(n\) 个糖果能量 \(a_i\) 和 \(n\) 个药片能量 \(b_i\),每个 \(a_i\) 和 \(b_i\) ...

随机推荐

  1. 谈谈java中的并发(一)

    一.并发的定义 并发:对于这个概念一直就是没怎么搞懂,就是感觉特别的生疏,(自己从从字面上理解就是多个东西,一起出发),所以就上网上查了一些资料: 同时拥有两个或多个线程,如果程序在单核处理器上运行, ...

  2. java scoket Blocking 阻塞IO socket通信二

    在上面一节中,服务端收到客户端的连接之后,都是new一个新的线程来处理客户端发送的请求,每次new 一个线程比较耗费系统资源,如果100万个客户端,我们就要创建100万个线程,相当的 耗费系统的资源, ...

  3. python文件处理-将图像根据坐标画矩形标记

    内容涉及:文件遍历,选取csv后缀文件,用cv操作图片 import csv import os import sys import numpy as np import copy import sh ...

  4. SpringBoot中VO,DTO,DO,PO的概念、区别和用处

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/zhuguang10/article/de ...

  5. 断路器Hystrix(Feign)

    上一篇中我们讲了 断路器Hystrix(Ribbon) 本章讲解Feign+Hystrix已经Request请求传递,各种奇淫技巧…. - Hystrix Hystrix支持回退概念:当 断路器 打开 ...

  6. linux系统,没有安装任何编辑器的情况,如何操作文件

    [清空文件] echo  " " > filename [添加内容] echo "123" >> filename

  7. mongodb 3.x以上版本与mongodb 2.x版本语法区别

    2.x const MongoClient = require('mongodb').MongoClient; const url = 'mongodb://localhost:27017/test' ...

  8. Python3笔记006 - 2.3 变量

    第2章 python语言基础 python语法特点 保留字与标识符 变量 数据类型 运算符 输入和输出 2.3 变量 在python中,不需要先声明变量类型,直接赋值即可创建各种类型的变量. 1.定义 ...

  9. Nuxt使用axios跨域问题解决方法

    Nuxt 是 Vue 项目服务器端渲染(SSR)解决方案.而在使用时,就会遇到前后端分离情况下的域名或端口不一致导致的跨域问题.本文将介绍如何通过设置代理解决 Nuxt 与 axios 集成的跨域问题 ...

  10. 为什么是link-visited-hover-active原理这样的特殊

    前言 通常我们在设置链接的一些伪类(link,visited,hover,active)样式时,要让不同的状态显示正确的样式,我们需要按一定的顺序设置这些伪类的样式.这里我就按css2规范中推荐的顺序 ...