[LOJ2290] [THUWC2017] 随机二分图
题目链接
LOJ:https://loj.ac/problem/2290
洛谷:https://www.luogu.org/problemnew/show/P4547
Solution
首先考虑只有第一类边的情况,那么每种完美匹配一定会由\(n\)个边组组成,概率就是\(1/2^n\),对答案贡献为\(1\),那么问题就转化成了统计完美匹配个数。
设\(f[s1][s2]\)表示当前左边情况为\(s1\),右边为\(s2\),在把其他的点填满可以得到的完美匹配的种类数,然后就是普及组\(dp\),复杂度\(O(2^{2n})\),但是这样会重复计数,而且复杂度不对。
如果我们把\(s1\)严格每次都从高位到低位转移,然后上记忆化搜索,复杂度可以降到\(O(2^n\cdot n^2)\),且不会重复计数。
考虑其他两类边,我们硬点这些边都是单独的,概率\(50\%\),但是这样会算不对,第二类边组在两条边都选的时候贡献的概率为\(25\%\),但是应该是\(50\%\),所以我们多加一个\(25\%\)的边组就好了,同理第三类边组添加一个概率为\(-25\%\)的边组,然后改一改上面的\(dp\),记搜转移就好了,\(f\)开不下可以用\(\rm map\)。
#include<bits/stdc++.h>
using namespace std;
void read(int &x) {
x=0;int f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}
void print(int x) {
if(x<0) putchar('-'),x=-x;
if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}
#define lf double
#define ll long long
#define pii pair<int,int >
#define vec vector<int >
#define pb push_back
#define mp make_pair
#define fr first
#define sc second
#define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++)
const int maxn = 1e4+10;
const int inf = 1e9;
const lf eps = 1e-8;
const int mod = 1e9+7;
const int inv2 = 5e8+4;
const int inv4 = 2.5e8+2;
int add(int x,int y) {return x+y>=mod?x+y-mod:x+y;}
int del(int x,int y) {return x-y<0?x-y+mod:x-y;}
int mul(int x,int y) {return 1ll*x*y-1ll*x*y/mod*mod;}
map<int,int > f;
int a[maxn],b[maxn],cnt,n,m;
int dfs(int s) {
if(s==(1<<(n<<1))-1) return 1;
if(f.find(s)!=f.end()) return f[s];int now=0,ans=0;
for(int i=n-1;~i;i--) if(!(s&(1<<i))) {now=1<<i;break;}
for(int i=1;i<=cnt;i++)
if(!(a[i]&s)&&(now&a[i])) ans=add(ans,mul(b[i],dfs(s|a[i])));
return f[s]=ans;
}
int main() {
read(n),read(m);
for(int i=1,s,s2,t,x,y;i<=m;i++) {
read(t),read(x),read(y);x--,y--;
s=1<<x|(1<<(y+n));a[++cnt]=s,b[cnt]=inv2;
if(!t) continue;read(x),read(y);x--,y--;
s2=1<<x|(1<<(y+n));a[++cnt]=s2,b[cnt]=inv2;
if(s&s2) continue;
a[++cnt]=s|s2,b[cnt]=t==1?inv4:mod-inv4;
}write(mul(dfs(0),(int)pow(2,n)));
return 0;
}
[LOJ2290] [THUWC2017] 随机二分图的更多相关文章
- [思路题][LOJ2290][THUWC2017]随机二分图:状压DP+期望DP
分析 考虑状压DP,令\(f[sta]\)表示已匹配状态是\(sta\)(\(0\)代表已匹配)时完美匹配的期望数量,显然\(f[0]=1\). 一条边出现了不代表它一定在完美匹配内,这也导致很难去直 ...
- [THUWC2017]随机二分图
题目大意 给一张二分图,有左部点和右部点. 有三种边,第一种是直接从左部点连向右部点,出现概率为50%. 第二种边一组里有两条边,这两条边同时出现或者不出现,概率都是50%. 第三种边一组里有两条边, ...
- Luogu4547 THUWC2017 随机二分图 概率、状压DP
传送门 考虑如果只有$0$组边要怎么做.因为$N \leq 15$,考虑状压$DP$.设$f_i$表示当前的匹配情况为$i$时的概率($i$中$2^0$到$2^{N-1}$表示左半边的匹配情况,$2^ ...
- BZOJ5006 THUWC2017随机二分图(概率期望+状压dp)
下称0类为单边,1类为互生边,2类为互斥边.对于一种匹配方案,考虑其出现的概率*2n后对答案的贡献,初始为1,如果有互斥边显然变为0,否则每有一对互生边其贡献*2.于是有一个显然的dp,即设f[S1] ...
- THUWC2017随机二分图
题面链接 洛谷 sol 唯一的重点是拆边... 0的不管,只看1.2. 先无论如何把两条边的边权赋为\(0.5\)然后我们发现如果两个都选了. 对于第一种边,我们发现如果\(\frac{1}{2} * ...
- [BZOJ5006][LOJ#2290][THUWC2017]随机二分图(概率+状压DP)
https://loj.ac/problem/2290 题解:https://blog.csdn.net/Vectorxj/article/details/78905660 不是很好理解,对于边(x1 ...
- P4547 [THUWC2017]随机二分图(状压,期望DP)
期望好题. 发现 \(n\) 非常小,应该要想到状压的. 我们可以先只考虑 0 操作. 最难的还是状态: 我们用 \(S\) 表示左部点有哪些点已经有对应点, \(T\) 表示右部点有哪些点已经有对应 ...
- 题解 洛谷 P4547 【[THUWC2017]随机二分图】
根据题意,题目中所求的即为所有\(n!\)种完美匹配的各自的出现概率之和再乘上\(2^n\)的值. 发现\(n\)很小,考虑状压\(DP\).设\(f_{S,T}\)为左部图匹配情况为\(S\),右部 ...
- 【THUWC2017】随机二分图(动态规划)
[THUWC2017]随机二分图(动态规划) 题面 BZOJ 洛谷 题解 如果每天边的限制都是\(0.5\)的概率出现或者不出现的话,可以把边按照二分图左侧的点的编号排序,然后设\(f[i][S]\) ...
随机推荐
- 4、spark streaming+kafka
一.Receiver模式 1. receiver模式原理图 在SparkStreaming程序运行起来后,Executor中会有receiver tasks接收kafka推送过来的数据.数据会被持久化 ...
- bash循环得到日期目录
#!/bin/bash today=$(date "+%Y%m%d") echo 'today is :'${today} single_input="raw_data/ ...
- Spyder汉化问题
首先感谢李增海大神,以下内容来源于http://www.lizenghai.com 必备条件 1.已安装Spyder 2.Spyder版本在3.X以上 Spyder安装: 1.anaconda下,co ...
- 数据结构实验之排序四:寻找大富翁(SDUT 3401)
#include <stdio.h> #include <stdlib.h> #include <string.h> void Swap(int a[], int ...
- 最近在弄ionic3的时候遇到的一些问题(遇到就更新)
问题一(install提示errno -4048 和管理员权限) npm install npm ERR! code EPERM npm ERR! errno - npm ERR! syscall u ...
- MySQL事务部分回滚-回滚到指定保存点
我们可以在mysql事务处理过程中定义保存点(SAVEPOINT),然后回滚到指定的保存点前的状态. 定义保存点,以及回滚到指定保存点前状态的语法如下. 定义保存点---SAVEPOINT 保存点名; ...
- gradle 使用maven repository 的设置
repositories { //Maven中心库(http://repo1.maven.org/maven2) mavenCentral() //本地库,local repository ...
- Mysql按日、周、月进行分组统计
我们在用 Mysql 制作数据可视化图表时候,经常需要按照天.周.月等不同的粒度对数据进行分组统计.而我们的时间可能是 “2017/12/5 0:0:0” 这种准确的时间. 所以在进行分组之前我们需要 ...
- JVM常用命令和性能调优建议
一.查看jvm常用命令jinfo:可以输出并修改运行时的java 进程的opts. jps:与unix上的ps类似,用来显示本地的java进程,可以查看本地运行着几个java程序,并显示他们的进程 ...
- 十三、postman导出java代码
导出成java的OkHttp代码 使用Junit进行接口自动化测试 使用fastJSON解析json字符串 创建个实体类 package com.netease.AcFunTest; public c ...