题解 洛谷 P4547 【[THUWC2017]随机二分图】
根据题意,题目中所求的即为所有\(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]随机二分图】的更多相关文章
- P4547 [THUWC2017]随机二分图(状压,期望DP)
期望好题. 发现 \(n\) 非常小,应该要想到状压的. 我们可以先只考虑 0 操作. 最难的还是状态: 我们用 \(S\) 表示左部点有哪些点已经有对应点, \(T\) 表示右部点有哪些点已经有对应 ...
- 【BZOJ2830/洛谷3830】随机树(动态规划)
[BZOJ2830/洛谷3830]随机树(动态规划) 题面 洛谷 题解 先考虑第一问. 第一问的答案显然就是所有情况下所有点的深度的平均数. 考虑新加入的两个点,一定会删去某个叶子,然后新加入两个深度 ...
- [LOJ2290] [THUWC2017] 随机二分图
题目链接 LOJ:https://loj.ac/problem/2290 洛谷:https://www.luogu.org/problemnew/show/P4547 Solution 首先考虑只有第 ...
- 题解 洛谷P5018【对称二叉树】(noip2018T4)
\(noip2018\) \(T4\)题解 其实呢,我是觉得这题比\(T3\)水到不知道哪里去了 毕竟我比较菜,不大会\(dp\) 好了开始讲正事 这题其实考察的其实就是选手对D(大)F(法)S(师) ...
- 题解 洛谷 P3396 【哈希冲突】(根号分治)
根号分治 前言 本题是一道讲解根号分治思想的论文题(然鹅我并没有找到论文),正 如论文中所说,根号算法--不仅是分块,根号分治利用的思想和分块像 似却又不同,某一篇洛谷日报中说过,分块算法实质上是一种 ...
- 题解-洛谷P5410 【模板】扩展 KMP(Z 函数)
题面 洛谷P5410 [模板]扩展 KMP(Z 函数) 给定两个字符串 \(a,b\),要求出两个数组:\(b\) 的 \(z\) 函数数组 \(z\).\(b\) 与 \(a\) 的每一个后缀的 L ...
- 题解-洛谷P4229 某位歌姬的故事
题面 洛谷P4229 某位歌姬的故事 \(T\) 组测试数据.有 \(n\) 个音节,每个音节 \(h_i\in[1,A]\),还有 \(m\) 个限制 \((l_i,r_i,g_i)\) 表示 \( ...
- 题解-洛谷P4724 【模板】三维凸包
洛谷P4724 [模板]三维凸包 给出空间中 \(n\) 个点 \(p_i\),求凸包表面积. 数据范围:\(1\le n\le 2000\). 这篇题解因为是世界上最逊的人写的,所以也会有求凸包体积 ...
- 题解-洛谷P4859 已经没有什么好害怕的了
洛谷P4859 已经没有什么好害怕的了 给定 \(n\) 和 \(k\),\(n\) 个糖果能量 \(a_i\) 和 \(n\) 个药片能量 \(b_i\),每个 \(a_i\) 和 \(b_i\) ...
随机推荐
- JavaWeb网上图书商城完整项目--26.注册页面之验证码换一张实现
我们现在要实现点击换一张的时候实现验证码的修改 我们首先在html添加函数点击事件: <%@ page language="java" contentType="t ...
- php - 如何解决CURL错误( 7 ): 无法连接到主机?
php - 如何解决CURL错误( 7 ): 无法连接到主机? 1. 问题描述 调用第三方接口,本地调用一切ok,线上调用失败! 本地通过curLRequest()方法调用第三方接口时,curl_er ...
- ThinkPHP5生成二维码图片与另一张背景图片进行合成
1.PHP方法 public function do_qrcode(){ Vendor('Qrcode.phpqrcode'); Vendor('Qrcode.Compress'); $object ...
- Python 简明教程 --- 12,Python 字典
微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 代码写的越急,程序跑得越慢. -- Roy Carlson 目录 Python 字典是另一种非常实用 ...
- HDU3686 Traffic Real Time Query【缩点+lca】
题目 City C is really a nightmare of all drivers for its traffic jams. To solve the traffic problem, t ...
- 《UNIX环境高级编程》(APUE) 笔记第九章 - 进程关系
9 - 进程关系 GitHub 地址 1. 进程组 每个进程除了有一个 进程 ID 外,还属于一个 进程组 .进程组是一个或多个进程的 集合 ,通常,它们是在同一作业中结合起来的,同一进程组中的各进程 ...
- 简单几步让CentOS系统时间同步
在使用CentOS系统的时候,我们可能会遇到时间不准的问题,那我们如何解决这个我问题呢,下面就来教大家一个CentOS系统时间同步的方法,希望大家可以解决自己所存在的疑问. CentOS系统时间同步的 ...
- JavaScript图形实例:迭代函数系统生成图形
迭代函数系统(Iterated Function System,IFS)可以用来创建分形图案,它是分形理论的重要分支,也是分形图形处理中最富生命力而且最具有广阔应用前景的领域之一.这一工作最早可以追溯 ...
- Python 简明教程 --- 22,Python 闭包与装饰器
微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 当你选择了一种语言,意味着你还选择了一组技术.一个社区. 目录 本节我们来介绍闭包与装饰器. 闭包与 ...
- MACOS使用VScode进行C语言编程
[B站有同步视频教程] 安装VScode 从官网下载vscode安装https://code.visualstudio.com/ 安装code runner插件 配置code runner从终端输出 ...