zoukankan      html  css  js  c++  java
  • 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));
    }
    
  • 相关阅读:
    apache反向代理和负载均衡
    maven学习3,如何创建一个web项目
    初识maven及其安装步骤!!
    初识Eclipse!!
    登录页面!!!
    面向对象的三大要素
    【转载】fatal error C1010: unexpected end of file while looking for precompiled header directive
    C++ 读取XML 和TXT
    python +Libsvm 配置
    C++ 引用 和 指针 心得
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/6804042.html
Copyright © 2011-2022 走看看