zoukankan      html  css  js  c++  java
  • Topcoder SRM713 DFSCount

    Description

    传送门


    Solution

    注意到(DFS)的时候每次选择一个(DFS)树的子树后必然会走所有子树中的节点,所以原问题变成所有子树内的顺序乘子树外的顺序。

    这样可以将还没有经过的节点状压,进行记忆化搜索。(DFS)树的子树个数就是去掉当前点之后的连通块个数,用并查集维护即可。

    总答案就是分别将每个节点当做(DFS)树的树根进行一遍记忆化搜索的答案的和。


    Code

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    
    using namespace std;
    
    #define ll long long
    
    const int N = 20;
    
    int a[N][N], all, n;
    
    ll dp[N][114514];
    
    class DFSCount
    {
    	public:
    		long long count(vector<string> G);	
    };
    
    int Find(int x, int fa[])
    {
    	return fa[x] == x ? x : fa[x] = Find(fa[x], fa);
    }
    
    ll Dfs(int x, int zt)
    {
    	if (dp[x][zt]) return dp[x][zt];
    	if (zt == all) return dp[x][zt] = 1;
    	int s = 0, cnt = 0, tmp[50], fa[N];
    	ll f[N];
    	for (int i = 0; i < n; i++) fa[i] = i;
    	for (int i = 0; i < n; i++)	
    		for (int j = 0; j < n; j++)
    			if (!(zt & (1 << i)) && !(zt & (1 << j)) && a[i][j]) 
    				fa[Find(i, fa)] = Find(j, fa);
    	for (int i = 0; i < n; i++)
    	{
    		f[i] = 0;
    		if (!(zt & (1 << i)) && a[x][i]) tmp[++cnt] = i;
    		if (Find(i, fa) == i && !(zt & (1 << i))) s++;
    	}
    	for (int i = 1; i <= cnt; i++)
    	{
    		int neww = all, ff = Find(tmp[i], fa);
    		for (int j = 0; j < n; j++) 
    			if (!(zt & (1 << j)) && Find(j, fa) == ff) neww ^= 1 << j;
    		neww |= 1 << tmp[i];
    		f[ff] += Dfs(tmp[i], neww);
    	}
    	ll ans = 1;
    	for (int i = 0; i < n; i++)
    		if (f[i]) ans *= f[i];
    	for (int i = 1; i <= s; i++) ans = 1LL * ans * i;
    	return dp[x][zt] = ans;
    } 
    
    long long DFSCount::count(vector<string> G)
    {
    	n = G.size(); all = (1 << n) - 1;
    	for (int i = 0; i < n; i++)
    		for (int j = 0; j < n; j++)	
    			if (G[i][j] == 'Y')
    				a[i][j] = 1;
    	ll ans = 0;
    	for (int i = 0; i < n; i++) ans += Dfs(i, 1 << i); 
    	return ans;
    }
    
  • 相关阅读:
    由于取消了脚本支持,无法查看访问统计,也办法放gg广告了,本站更新速度降低.
    关于ASP循环表格的问题之解答
    STL中map用法详解
    vector与list的区别
    mysql联合索引 sql索引使用
    如何让linux/Centos 32位支持大于4G内存
    mysql事务
    Mysql InnoDB中的查询事务模式与锁定select ..for update
    linux 查看系统版本
    如何在64位的Linux中运行32位的应用程序
  • 原文地址:https://www.cnblogs.com/Tian-Xing-Sakura/p/13259858.html
Copyright © 2011-2022 走看看