zoukankan      html  css  js  c++  java
  • [THUWC2017] 随机二分图

    [题目链接]

    https://loj.ac/p/2290

    [题解]

    首先考虑所有边满足 (t = 0) 的情况。

    不妨设 (dp_{s1 , s2}) 表示左侧未选集合为 (s1) , 右侧为 (s2) 的完美匹配数期望。

    根据期望的线性性 , 有 (dp_{s1 , s2} = sum_{i in s1}sum_{j in s2}{p_{i , j} cdot dp_{s1 oplus bit_{i} , s2 oplus bit_{j}}})

    直接这样计算会将本质相同的一组完美匹配贡献多次 , 因此转移时可以考虑强制去掉最高位 / 最低位。

    接着考虑存在 (t eq 0) 的情况。

    假设 (t = 1) , 不妨将 ((u , v))((a , b)) 这两条边当作 "(0) 类边" 处理 , 将其概率均设为 (frac{1}{2})。这样在计算答案时 , ((u , v)) , ((a , b)) 二者出现一条的概率为 (frac{1}{2}) , 符合要求 , 但 ((u , v)) , ((a , b)) 二者同时出现的概率变为了 (frac{1}{4}) , 与要求的 (frac{1}{2}) 不符。 因此不妨加入一条 "四元边" ((u , v , a , b)) , 其出现概率为 (frac{1}{4})。 对于 (t = 2) 的情况则加入一条概率为 (-frac{1}{4}) 的边。虽然这样不符合常理 , 但根据期望的线性性质是可行的 。

    注意当 ((u , v)) , ((a , b)) 存在公共点时二者不可兼得 , 故不需要加入 "四元边"。

    状态数很大 , 数组存不下 , 可以用一个 (unordered)_(map) 存储。

    时间复杂度 : (O(?))

    [代码]

    #include<bits/stdc++.h>
    
    using namespace std;
    
    typedef long long LL;
    
    #define rep(i , l , r) for (int i = (l); i < (r); ++i)
    
    const int MN = 5005;
    const int mod = 1e9 + 7 , inv2 = 500000004, inv4 = 250000002;
    
    unordered_map < int , int > dp , f;
    
    int w[MN] , e[MN] , N , M , tot;
    
    inline void inc(int &x , int y) {
    	x = x + y < mod ? x + y : x + y - mod;
    }
    inline int dfs(int s) {
    	if (!s) return 1;
    	if (f[s]) return dp[s];
    	int res = 0;
    	f[s] = 1;
    	for (int i = 1; i <= tot; ++i)
    		if ((e[i] & s) == e[i] && e[i] > s / 2)
    			inc(res , 1ll * w[i] * dfs(s ^ e[i]) % mod);
    	return dp[s] = res;
    }
    int main() {
    	 
    	 scanf("%d%d" , &N , &M);
    	 for (int i = 1; i <= M; ++i) {
    	 	 int op , u , v , a , b;
    	 	 scanf("%d%d%d" , &op , &u , &v);
    	 	 --u , --v;
    	 	 e[++tot] = (1 << u) | (1 << v + N); w[tot] = inv2;
    	 	 if (!op) continue;
    	 	 scanf("%d%d" , &a , &b);
    	 	 --a , --b;
    	 	 e[++tot] = (1 << a) | (1 << b + N); w[tot] = inv2;
    	 	 if (e[tot] & e[tot - 1]) continue;
    	 	 e[tot + 1] = e[tot] | e[tot - 1];
    	 	 w[++tot] = (op == 1 ? inv4 : mod - inv4);
    	 }
    	 printf("%d
    " , 1ll * (1 << N) * dfs((1 << (2 * N)) - 1) % mod);
         return 0;
    }
  • 相关阅读:
    Spring mvc时间格式处理
    dubbo升级spring4与cxf
    dom4j使用总结
    java utils
    ES6
    ES6
    javascript常用方法
    ES6
    ES6
    ES6
  • 原文地址:https://www.cnblogs.com/evenbao/p/14358990.html
Copyright © 2011-2022 走看看