• Codeforces 599E Sandy and Nuts(状压DP)


    题目链接 Sandy and Nuts

    题意大概就是给出限制条件求出在该限制条件下树的种数。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define REP(i, n)	for (int i(0); i <  (n); ++i)
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    
    typedef long long LL;
    
    const int N = 15;
    const int maxS = 10010;
    const int maxQ = 210;
    
    int n, m, q, all;
    LL f[N][maxS];
    int a[maxQ], b[maxQ], c[maxQ];
    int e[N][N];
    
    inline in(int i, int S){ return (S >> i) & 1; }
    
    LL DP(int u, int S){
    	LL &ret = f[u][S];
    	if (ret != -1) return ret;
    
    	ret = 0;
    	int St = S ^ (1 << u);
    	int t; for (t = 0; t < n; ++t) if (in(t, St)) break;
    
    	for (int __S = St; __S; (--__S) &= St) if (in(t, __S)){
    		bool flag = true;
    		REP(i, n) if (i != u){
    			REP(j, n) if (j != u){
    				if (e[i][j] && (in(i, __S) ^ in(j, __S))){
    					flag = false;
    					break;
    				}
    			}
    
    			if (!flag) break;
    		}
    
    		if (!flag) continue;
    
    		int v, cnt = 0;
    		REP(i, n){
    			if (e[u][i] && in(i, __S)){
    				++cnt;
    				v = i;
    			}
    		}
    
    		if (cnt >= 2) continue;
    		
    		rep(i, 1, q){
    			if (c[i] == u && in(a[i], __S) && in(b[i], __S)){
    				flag = false; break;
    			}
    
    			if (in(c[i], __S) && (!in(a[i], __S) || !in(b[i], __S))){
    			       	flag = false; break;
    			}
    		}
    
    		if (!flag) continue;
    
    		if (cnt == 1)  ret += DP(v, __S) * DP(u, S ^ __S);
    		else  REP(v, n)  if (in(v, __S)) ret += DP(v, __S) * DP(u, S ^ __S);
    	}
    
    	return ret;
    }
    				
    
    int main(){
    
    	scanf("%d%d%d", &n, &m, &q);
    	rep(i, 1, m){
    		int x, y;
    		scanf("%d%d", &x, &y);
    		--x, --y;
    		e[x][y] = e[y][x] = 1;
    	}
    
    	rep(i, 1, q){
    		scanf("%d%d%d", a + i, b + i, c + i);
    		--a[i], --b[i], --c[i];
    	}
    
    	all = (1 << n) - 1;
    	memset(f, -1, sizeof f);
    	REP(i, n) f[i][1 << i] = 1;
    
    	return 0 * printf("%lld
    ", DP(0, all));
    }
    
  • 相关阅读:
    redhat 7.2 内网安装docker
    使用dockerfile 创建ubuntu ssh镜像
    docker 离线环境安装oracle
    redhat 6.6 、7、Centos7离线安装docker
    用命令行管理aws s3
    Anaconda介绍、安装及使用教程
    python2 编码问题万能钥匙
    从mongo数据库中导出数据的方法
    MongoDB学习第三篇 --- Insert操作
    MongoDB学习笔记(一)-Insert操作
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/6804042.html
Copyright © 2020-2023  润新知