一句话题意:求一个 \(n\) 点带编号的连通图数量。

吐槽一下:好好一道计数 dp 为什么不加取余????逼着选手写高精度的出题人应该拎出去烧……哦楼天城是出题人是吧哦当我没说我什么都没说我现在就把我拎出去 QAQ

这道题就很计数 dp 那个味对吧,所以设 \(f_i\) 为 \(i\) 个点的连通图数量。

但这样非常难算,你想我们数数 dp 是围绕一个基准,按照这个基准来划分子问题,一个连通图拿什么当基准?正难则反,考虑计算不连通图的数量,因为这样每一个连通块就自然而然给了我们划分出来子问题的空间了。我们记 \(g_i\) 为 \(i\) 个点非连通图数量。以下为了叙述方便我们令 \(b2_{i} = 2^{(i - 1)i / 2}\),放在这题的含义就是:有 \(i\) 个点共能产生多少张图。

我们先考虑 1 号点,以 1 号点所在连通块大小作为我们划分的基准,这样就分成了一些子问题了。我们令一号店所在连通块大小为 \(k\),也就是说除了 \(1\) 点外要选 \((k - 1)\) 个点。这样的连通块一共有 \(C_{n - 1}^{k - 1}\) 种。连通块内部有 \(f(k)\) 种方案。连通块外部呢?管它的,随便它们联通不联通,反正只要不和我们选出来的 \((k - 1)\) 个点和 \(1\) 连边就好了。所以答案就是 \(g_{x} = \sum\limits_{k = 1}^{x - 1}C_{x - 1}^{k - 1}f_xb2_{x - k}, f_x = b2_{x} - g_{x}\)

毒瘤就毒瘤在写高精度,这玩意儿就算是暴力都好久没写了,很担心自己哪里细节写挂了,反正高精度打了七八十来行,高兴极了

//SIXIANG
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#define MAXN 100000
#define QWQ cout << "QWQ" << endl;
using namespace std;
struct Bignum {
string num;
Bignum operator + (const Bignum &other) const {
string s1 = num, s2 = other.num, rest = "";
if(s1.size() < s2.size()) swap(s1, s2);
while(s2.size() < s1.size()) s2 = "0" + s2;
reverse(s1.begin(), s1.end());
reverse(s2.begin(), s2.end()); int len = s1.size(), a = 0, b = 0, c = 0, d = 0;
for(int p = 0; p < len; p++) {
a = s1[p] - '0', b = s2[p] - '0';
c = (a + b + d) % 10, d = (a + b + d) / 10;
rest += char(c + '0');
}
if(d) rest += char(d + '0');
reverse(rest.begin(), rest.end()); string ans = "";
bool lead = 0;
for(int p = 0; p < rest.size(); p++) {
if(!lead)
if(rest[p] != '0')
lead = 1;
if(lead)
ans += rest[p];
} return (Bignum){ans};
}
Bignum operator - (const Bignum &other) const {
string s1 = num, s2 = other.num;
while(s2.size() < s1.size()) s2 = "0" + s2;
reverse(s1.begin(), s1.end());
reverse(s2.begin(), s2.end()); int a = 0, b = 0, c = 0, d = 0;
string rest = "", ans = "";
for(int p = 0; p < s1.size(); p++) {
a = s1[p] - '0', b = s2[p] - '0';
c = a + d - b;
if(c < 0) c += 10, d = -1;
else d = 0;
rest += char(c + '0');
}
bool lead = 0;
for(int p = rest.size() - 1; p >= 0; p--) {
if(!lead)
if(rest[p] != '0')
lead = 1;
if(lead)
ans += rest[p];
}
return (Bignum){ans};
}
Bignum operator * (const Bignum &other) const {
string s1 = num, s2 = other.num;
reverse(s1.begin(), s1.end());
reverse(s2.begin(), s2.end());
int a[5010], b[5010], c[10010];
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
memset(c, 0, sizeof(c)); int len1 = s1.size(), len2 = s2.size();
for(int p = 0; p < len1; p++)
a[p] = s1[p] - '0';
for(int p = 0; p < len2; p++)
b[p] = s2[p] - '0';
for(int p = 0; p < len1; p++)
for(int i = 0; i < len2; i++)
c[p + i] += a[p] * b[i];
for(int p = 0; p <= len1 + len2; p++)
c[p + 1] += c[p] / 10, c[p] %= 10; bool lead = 0;
string rest = "";
for(int p = len1 + len2 + 1; p >= 0; p--) {
if(!lead)
if(c[p] != 0)
lead = 1;
if(lead)
rest += char(c[p] + '0');
}
return (Bignum){rest};
}
};
Bignum b2[1260], C[60][60], f[260], g[260];
int n;
int id(int n) {return n * (n - 1) / 2;}
void prepare() {
b2[0].num = "1";
for(int p = 1; p <= 1250; p++)
b2[p] = b2[p - 1] * (Bignum){"2"};
for(int p = 0; p <= 55; p++)
for(int i = 0; i <= 55; i++)
C[p][i].num = "0";
C[0][0].num = C[1][0].num = C[1][1].num = "1";
for(int p = 2; p <= 55; p++) {
C[p][0].num = "1";
for(int i = 1; i <= p; i++)
C[p][i] = C[p - 1][i - 1] + C[p - 1][i];
} f[1].num = "1", g[1].num = "0";
for(int p = 2; p <= 55; p++)
f[p].num = g[p].num = "0";
for(int i = 2; i <= 50; i++) {
for(int k = 1; k < i; k++) {
Bignum tmp = C[i - 1][k - 1] * f[k] * b2[id(i - k)];
g[i] = g[i] + tmp;
}
f[i] = b2[id(i)] - g[i];
}
}
int init() {
cin >> n;
if(!n) return -1;
cout << f[n].num << endl;
} int main() {
prepare();
while(1)
if(init() < 0) return 0;
}

POJ1737 连通图的更多相关文章

  1. [poj1737]Connected Graph(连通图计数)

    题意:输出题中带有$n$个标号的图中连通图的个数. 解题关键: 令$f(n)$为连通图的个数,$g(n)$为非联通图的个数,$h(n)$为总的个数. 则$f(n) + g(n) = h(n)$ 考虑标 ...

  2. BZOJ 3237: [Ahoi2013]连通图

    3237: [Ahoi2013]连通图 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1161  Solved: 399[Submit][Status ...

  3. dfs判断连通图(无向)

    在图论中,连通图基于连通的概念.在一个无向图 G 中,若从顶点vi到顶点vj有路径相连(当然从vj到vi也一定有路径),则称vi和vj是连通的.如果 G 是有向图,那么连接vi和vj的路径中所有的边都 ...

  4. bfs判断连通图(无向)

    在图论中,连通图基于连通的概念.在一个无向图 G 中,若从顶点vi到顶点vj有路径相连(当然从vj到vi也一定有路径),则称vi和vj是连通的.如果 G 是有向图,那么连接vi和vj的路径中所有的边都 ...

  5. 【poj1737】 Connected Graph

    http://poj.org/problem?id=1737 (题目链接) 题意 求n个节点的无向连通图的方案数,不取模w(゚Д゚)w Solution 刚开始想了个第二类斯特林数,然而并不知道怎么求 ...

  6. POJ1737 Connected Graph

    Connected Graph Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 3156   Accepted: 1533 D ...

  7. POJ2762 Going from u to v or from v to u?(判定单连通图:强连通分量+缩点+拓扑排序)

    这道题要判断一张有向图是否是单连通图,即图中是否任意两点u和v都存在u到v或v到u的路径. 方法是,找出图中所有强连通分量,强连通分量上的点肯定也是满足单连通性的,然后对强连通分量进行缩点,缩点后就变 ...

  8. 无向连通图求割边+缩点+LCA

    Network Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 7082   Accepted: 2555 Descripti ...

  9. Noip2014 提高组 T2 联合权值 连通图+技巧

    联合权值 描述 无向连通图 G 有 n 个点,n-1 条边.点从 1 到 n 依次编号,编号为 i 的点的权值为 WiWi, 每条边的长度均为 1.图上两点(u, v)的距离定义为 u 点到 v 点的 ...

  10. [kuangbin带你飞]专题九 连通图

        ID Origin Title   76 / 163 Problem A POJ 1236 Network of Schools   59 / 177 Problem B UVA 315 Ne ...

随机推荐

  1. Zabbix技术分享——docker组件编译使用教程

    docker是一个开源的应用容器引擎,基于Go语言并遵从Apache2.0协议开源,它可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发布到任何流行的Linux机器上,还可以实现 ...

  2. 【每日一题】【动态规划&二分】2022年2月9日-NC91 最长上升子序列(三)

    描述给定数组 arr ,设长度为 n ,输出 arr 的最长上升子序列.(如果有多个答案,请输出其中 按数值(注:区别于按单个字符的ASCII码值)进行比较的 字典序最小的那个) 方法1:双层循环实现 ...

  3. 【云原生 • DevOps】一文掌握容器管理工具 Rancher

    一.容器管理工具 Rancher 介绍Rancher 是一个开源的企业级全栈化容器部署及管理平台,其实就是一个 Docker 的图形化管理界面.它为容器提供基础架构服务,可以让 CNI 兼容的网络服务 ...

  4. JavaFX入门笔记

    JavaFX入门笔记 背景 Java选修课第四次实验 所需工具 IDEA JavaFX插件(需要Maven) JavaFX Scene Builder 参考资料 https://www.yiibai. ...

  5. 异常处理语法结构、yield生成器及其表达式

    今日内容回顾 目录 今日内容回顾 异常处理语法结构 异常处理实战应用 生成器对象 自定义range功能 yield冷门用法 yield与return对比 生成器表达式 笔试题 异常处理语法结构 异常处 ...

  6. DID 2022-12-02

    DID第二节课 最低工资对就业率影响(DID) 宾夕法尼亚VS新泽西的快餐店,用边界的好处:在用最低工资法之前,两地工资情况差不多,DID需要两期,92年11月实施,之前之后做电话访问. 数据越全的估 ...

  7. Cryptohack的Adrien's Signs解题思路

    题目如下: 输出的结果: 题目分析: 在原题的题目描述中并没有什么有用的消息,更多的信息是通过代码审计出来的.大致意思是,先把字节flag转换为二进制形式的字符串,然后判断字符串中每个字符,如果为1, ...

  8. [机器学习] Yellowbrick使用笔记6-分类可视化

    分类模型试图在一个离散的空间中预测一个目标,即为一个因变量实例分配一个或多个类别. 代码下载 分类分数可视化工具显示类之间的差异以及一些特定于分类器的可视化评估.我们目前已经实施了以下分类器评估: 分 ...

  9. [python]《Python编程快速上手:让繁琐工作自动化》学习笔记6

    1. 发送电子邮件和短信笔记(第16章)(代码下载) 1.1 发送电子邮件 简单邮件传输协议(SMTP)是用于发送电子邮件的协议.SMTP 规定电子邮件应该如何格式化.加密.在邮件服务器之间传递,以及 ...

  10. SPOJ PHONELST - Phone List | UVA11362 Phone List | LibreOJ10049. 「一本通 2.3 例 1」Phone List

    简要题意 \(t\) 组数据,每组数据给定 \(n\) 个长度不超过 \(10\) 的数字串,判断是否有两个字符串 \(A\) 和 \(B\),满足 \(A\) 是 \(B\) 的前缀,若有,输出 N ...