列表

详情


NC25672. 仙人掌

描述

对于一张无向连通图 G ,选定一个点 s 作为起点进行深度优先遍历,假设当前位于点 u,选出和 u 有边直接相连的之前未访问过的编号最小的点 v,递归到 v 继续进行深度优先遍历,如果找不到这样的点 v 则回溯。整个遍历过程结束后会得到一个序列,表示每个点第一次被访问的顺序。

(没有伪代码)

现在你需要找出所有带标号的仙人掌,点从 1 到 n 标号,满足以点 1 作为起点进行深度优先遍历得到的遍历序列恰好就是 1, 2, 3, ..., n,并给出满足条件的仙人掌的方案数。由于方案数可能很大,你只需要输出方案数对 1000000007 取模后的值。

这里仙人掌是指一个无向的连通图,这个图不存在自环,且任意一条边至多属于一个简单环。所谓简单环,是指在图中任取一个顶点作为起点,沿着不重复的边、经过不重复的点再次走到起点的闭合路径。两个仙人掌是不同的,当且仅当存在某一条边属于其中恰好一个仙人掌。

输入描述

第一行包含一个整数T
(1 <= T <= 5000),表示测试数据的组数,
每组测试数据都只有一行,包含一个整数n (1
<= n <= 5000),表示仙人掌的点数。

输出描述

对于每组测试数据,输出一行,包含一个整数,表示满足条件的仙人掌的方案数对
1000000007 取模后的值。

示例1

输入:

4
1
2
3
4

输出:

1
2
9
53

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 137ms, 内存消耗: 456K, 提交时间: 2019-05-16 11:36:10

#include <bits/stdc++.h>
using namespace std;

int main() {
	const uint64_t mod = 1000000007;
	auto add = [&mod] (const uint64_t& a, const uint64_t& b) { return a + b < mod ? a + b : a + b - mod; };
	auto mul = [&mod] (const uint64_t& a, const uint64_t& b) { return a * b % mod; };
	const size_t maxn = 5000;
	vector<uint64_t> dp0(maxn + 1), dp1(maxn + 1);
	dp0[1] = dp1[1] = 1;
	for (size_t i = 2; i <= maxn; ++i) for (size_t j = 1; j != i; ++j) {
		dp0[i] = add(dp0[i], mul(dp0[j], add(dp0[i - j], dp1[i - j])));
		dp1[i] = add(dp1[i], add(mul(dp0[j], dp1[i - j]), mul(dp1[j], add(dp0[i - j], dp1[i - j]))));
	}
	size_t T, n;
	cin >> T;
	while (T--) {
		cin >> n;
		cout << dp0[n] << endl;
	}
}

C++11(clang++ 3.9) 解法, 执行用时: 148ms, 内存消耗: 488K, 提交时间: 2019-05-13 09:01:45

#include<bits/stdc++.h>
using namespace std;
const int MAXN=5005;
const int Mod=1000000007;
int f[MAXN][2];
int main()
{
    f[1][0]=f[1][1]=1;
    for(int i=1;i+1<MAXN;i++)
        for(int j=0;j<i;j++)
        {
            f[i+1][0]=(f[i+1][0]+1LL*f[j+1][0]*(f[i-j][0]+f[i-j][1]))%Mod;
            f[i+1][1]=(f[i+1][1]+1LL*f[j+1][0]*f[i-j][1])%Mod;
            f[i+1][1]=(f[i+1][1]+1LL*f[j+1][1]*(f[i-j][0]+f[i-j][1]))%Mod;
        }
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        printf("%d\n",f[n][0]);
    }
    return 0;
}

上一题