zoukankan      html  css  js  c++  java
  • [SOJ #696]染色(2019-11-10考试)/[Atcoder MUJIN Programming Challenge C]Orange Graph

    题目大意

    有一个(n)个点(m)条边的简单无向连通图,初始为白色,可以执行操作让一些边变黑,要求使得操作后的图不存在黑色的奇环,且不能使得其他的任何变黑而还符合要求。问最后有多少可能结果。(nleqslant 21)(n-1leqslant mleqslant dfrac{n(n-1)}2)(原题中(nleqslant 16)

    题解

    因为不存在黑色的奇环,那么最后的黑边组成的图一定可以黑白染色,所以一定是一张二分图。又因为若最后黑图不连通,在两个环之间连一条边不会产生奇环,所以图一定连通。可以枚举每个点的颜色,若两个颜色不同的点之间有白边,改为黑色,最后判断黑图是否连通即可。原题判断连通是(O(n+m))(mathrm{dfs}),其实可以通过一些方法变为(O(n))(weng\_weijie)在拉这道题的时候加强的),故总复杂度(O(2^nn))

    卡点

    C++ Code:

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    const int N = 21;
    
    int n, m, E[N], ans, vis, S;
    void dfs(int u) {
    	vis |= 1 << u;
    	for (int i = E[u] & ~vis & (S >> u & 1 ? ~S : S); i; i = i & i - 1 & ~vis)
    		dfs(__builtin_ctz(i));
    }
    int main() {
    	std::ios::sync_with_stdio(0), std::cin.tie(0);
    	std::cin >> n >> m; const int U = 1 << (n - 1), I = (1 << n) - 1;
    	for (int i = 0, a, b; i < m; ++i)
    		std::cin >> a >> b, --a, --b, E[a] |= 1 << b, E[b] |= 1 << a;
    	for (S = 0; S < U; ++S) dfs(vis = 0), ans += vis == I;
    	std::cout << ans << '
    ';
    	return 0;
    }
    
  • 相关阅读:
    线程池和进程池
    初识数据库
    线程q
    event事件
    死锁和递归锁
    信号量
    PythonStudy——线程中的几种消息队列
    PythonStudy——GIL Global Interpreter Lock 全局解释器锁
    PythonStudy——异步回调
    PythonStudy——日志模块 logging
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/11846513.html
Copyright © 2011-2022 走看看