• 题解 小星星


    题目传送门

    题目大意

    给出 (n) 个点 (m) 条边的图,给出一个树,问有多少个映射使得树上的边在原图都出现过。

    (nle 17,mle n(n-1)/2)

    思路

    不难看出 (Theta(3^n imes n)) 的 dp,我们可以设 (f_{i,j,S}) 表示以 (i) 为根的子树映射到集合 (S),且 (i) 点映射到 (j) 的方案数。转移式显然。

    考虑容斥,我们可以设当前集合为 (S),那么我们在 dp 的时候钦定每个点只能映射到 (S)。这样的意思实际上就是消掉映射重复的方案。

    时间复杂度 (Theta(2^n imes n))

    ( exttt{Code})

    #include <bits/stdc++.h>
    using namespace std;
    
    #define Int register int
    #define int long long
    #define MAXN 25
    
    template <typename T> void read (T &x){char c = getchar ();x = 0;int f = 1;while (c < '0' || c > '9') f = (c == '-' ? -1 : 1),c = getchar ();while (c >= '0' && c <= '9') x = x * 10 + c - '0',c = getchar ();x *= f;}
    template <typename T,typename ... Args> void read (T &x,Args& ... args){read (x),read (args...);}
    template <typename T> void write (T x){if (x < 0) x = -x,putchar ('-');if (x > 9) write (x / 10);putchar (x % 10 + '0');}
    
    bool app[MAXN];
    int n,m,f[MAXN][MAXN];
    vector <int> G[MAXN],E[MAXN];
    
    void dfs (int u,int fa){
    	for (Int i = 1;i <= n;++ i) f[u][i] = 1;
    	for (Int v : G[u]) if (v ^ fa){
    		dfs (v,u);
    		for (Int i = 1;i <= n;++ i){
    			int s = 0;for (Int k : E[i]) s += f[v][k] * (app[i] & app[k]);
    			f[u][i] *= s;
    		}
    	}
    }
    
    signed main(){
    	read (n,m);
    	for (Int i = 1,u,v;i <= m;++ i) read (u,v),E[u].push_back (v),E[v].push_back (u);
    	for (Int i = 2,u,v;i <= n;++ i) read (u,v),G[u].push_back (v),G[v].push_back (u);
    	int ans = 0;for (Int S = 1;S < (1 << n);++ S){
    		memset (app,0,sizeof (app));int siz = n;
    		for (Int i = 1;i <= n;++ i) if (S >> i - 1 & 1) app[i] = 1,siz --;
    		dfs (1,0);for (Int i = 1;i <= n;++ i) ans += f[1][i] * (siz & 1 ? -1 : 1);
    	}
    	write (ans),putchar ('
    ');
    	return 0;
    }
    
  • 相关阅读:
    vue-cli
    respond.js
    dataTable调用接口渲染数据,没有数据,报错
    jq自定义鼠标右键菜单
    datatables通过ajax调用渲染数据,怎么根据数据给td添加class
    【C++ Primer 第11章 练习答案】2. 关联容器概述
    【Leetcode】1. Two Sum
    【C++】拷贝构造函数(深拷贝,浅拷贝)详解
    【图的遍历】广度优先遍历(DFS)、深度优先遍历(BFS)及其应用
    【C++ Primer 第十三章】4. 拷贝控制示例
  • 原文地址:https://www.cnblogs.com/Dark-Romance/p/14009159.html
Copyright © 2020-2023  润新知