题目大意

求两两互不同构的含n个点的简单图有多少种。

简单图是关联一对顶点的无向边不多于一条的不含自环的图。

a图与b图被认为是同构的是指a图的顶点经过一定的重新标号以后,a图的顶点集和边集能完全与b图一一对应。

题解

这个题是学习了Polya定理和群论以后的练手题,但是推了好久并没有推出来。。。。真的是太难辣。。。

首先我先说一下我错误的想法:

很容易就把这个题转化成了给\(K_n\)的完全图上的边进行二着色的问题,然后,由于在组合数学课程中经常接触到多边形着色,所以我就把这个题错误的转化成了在一个正\(\frac{n(n-1)}{2}\)边形的顶点上进行二着色的问题。然而对于n=1,2,3这种方法都是可行的,但是到了n=4的情况,这种方法就不可行了。我仔细观察了一下,发现这个转化不符合满足纯粹性和完备性。。。

然后就说一下正解吧。

首先我们考虑n = 4的情况,对于\(K_4\)进行二着色,我们很容易发现,由于图是可以任意扭转的,所以它的置换群实际上是一个对称群

那么对于点的每一个置换我们要计算对应的边的置换。

在一个置换中,考察一条边,如果这条边的两个节点位于相同的循环中,那么我们可以得出边的循环个数是点的循环个数的一半。

如果这条边的两个节点位于不同的循环中,那么我们画一画图就可以知道如果点的循环个数分别是a, b,那么边的循环个数就是gcd(a,b)。

根据这样的方法,我们就可以把点的置换转化为边的置换了。

下面的任务就是要枚举置换。

如果直接暴力,复杂度很高。

我们考虑这样的枚举(回溯)方法:

依次考虑每一种阶的循环的个数,然后暴力dfs即可。

现在假设我们已经枚举好了一个置换,那么这种置换的个数根据一些基本的排列组合知识,可以知道是:

\[\frac{n!}{\prod_{i = 1}^{cnt} Val_i * Num_i !}
\]

稍微解释一下这个式子。除以\(Val_i\)是因为圆形排列,除以\(Num_i\)是因为同阶循环的重复排列。

根据Polya定理,等价类的个数就是:

\[l = \frac{1}{N!} * \sum 2^m
\]

参考题解

事实上,这个题还有一个变态的做法:

就是上OEIS上查询通项公式。。。。

代码

#include <bits/stdc++.h>
const int mod = 997;
const int maxn = 1010;
using namespace std;
int n, cnt, ans;
int two[maxn], factor[maxn], val[maxn], num[maxn];
int pow(int n, int m) {
int ans = 1;
int b = m;
while(b) {
if(b & 1) ans = (ans * n) % mod;
b >>= 1;
n = (n*n) % mod;
}
return ans;
}
int inv(int n) {
return pow(n, mod-2);
}
int gcd(int a, int b) {
if(b == 0) return a;
else return gcd(b, a%b) % mod;
}
void init() {
factor[0] = factor[1] = two[0] = 1;
for(int i = 2; i <= 1000; i++) {
factor[i] = ((i % mod) * factor[i-1]) % mod;
}
for(int i = 1; i <= 1000; i++) {
two[i] = (two[i-1] * 2) % mod;
}
}
void dfs(int now_num, int left) {
if(left == 0) {
int sum1 = 0, sum2 = 1;
//sum1:这一种置换的循环个数
//sum2:这一种置换的个数
for(int i = 1; i <= cnt; i++) {
sum1 += (num[i] * (num[i] - 1) / 2 * val[i]) + (val[i]/2 * num[i]);
//前一部分:对于同一种循环中的不同循环的边的处理
for(int j = i + 1; j<= cnt; j++) {
sum1 += num[i] * num[j] * gcd(val[i], val[j]);
}
}
for(int i = 1; i <= cnt; i++) {
sum2 = (sum2 * pow(val[i], num[i])%mod*factor[num[i]])%mod;
}
sum2 = inv(sum2) * factor[n] % mod;
ans = (ans + pow(2, sum1) * sum2 % mod) % mod;
}
if(now_num > left) return;
dfs(now_num+1, left);
//这里的dfs放到外面可以降低常数:
//如果放在for循环里面,那么num数组中会多出许多0
//浪费时间。
for(int i = 1; i * now_num <= left; i++) {
val[++cnt] = now_num, num[cnt] = i;
dfs(now_num+1, left - i * now_num);
cnt--; //回溯
}
} int main() {
scanf("%d", &n);
init();
dfs(1, n);
ans = (ans * inv(factor[n])) % mod;
printf("%d", ans);
return 0;
}

[bzoj1488][HNOI2009]图的同构——Polya定理的更多相关文章

  1. [BZOJ1815&BZOJ1488]有色图/图的同构(Polya定理)

    由于有很多本质相同的重复置换,我们先枚举各种长度的点循环分别有多少个,这个暴搜的复杂度不大,n=53时也只有3e5左右.对于每种搜索方案可以轻易求出它所代表的置换具体有多少个. 但我们搜索的是点置换组 ...

  2. bzoj1488 [HNOI2009]图的同构 Burnside 引理

    题目传送门 bzoj1488 - [HNOI2009]图的同构 bzoj1815 - [Shoi2006]color 有色图(双倍经验) 题解 暴力 由于在做题之前已经被告知是 Burnside 引理 ...

  3. bzoj1488[HNOI2009]图的同构

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1488 1488: [HNOI2009]图的同构 Time Limit: 10 Sec  M ...

  4. BZOJ 1488: [HNOI2009]图的同构 [Polya]

    完全图中选出不同构的简单图有多少个 上题简化版,只有两种颜色....直接copy就行了 太诡异了,刚才电脑上多了一个不动的鼠标指针,然后打开显卡管理界面就没了 #include<iostream ...

  5. 【BZOJ1488】[HNOI2009]图的同构(Burside引理,Polya定理)

    [BZOJ1488][HNOI2009]图的同构(Burside引理,Polya定理) 题面 BZOJ 洛谷 题解 求本质不同的方案数,很明显就是群论这套理论了. 置换一共有\(n!\)个,考虑如何对 ...

  6. 【BZOJ1488】[HNOI2009]图的同构计数

    题目链接 题意 求 n 个点的同构意义下不同的图的数量.\((n\leq 60)\) Sol \(Polya\) 定理的练手题. 我们这里先把边的存在与否变成对边进行黑白染色,白色代表不存在,这样就变 ...

  7. Polya 定理 学习笔记

    群 群的定义 我们定义,对于一个集合 \(G\) 以及二元运算 \(\times\),如果满足以下四种性质,那我们就称 \((G,\times)\) 为一个群. 1. 封闭性 对于 \(a\in G, ...

  8. 【转】Polya定理

    转自:http://endlesscount.blog.163.com/blog/static/82119787201221324524202/ Polya定理 首先记Sn为有前n个正整数组成的集合, ...

  9. 【群论】polya定理

    对Polya定理的个人认识     我们先来看一道经典题目:     He's Circles(SGU 294)         有一个长度为N的环,上面写着“X”和“E”,问本质不同的环有多少个(不 ...

随机推荐

  1. Alpha冲刺Day5

    Alpha冲刺Day5 一:站立式会议 今日安排: 首先由于经过黄腾飞短暂的测试,发现导入导出仍然有一些问题,今天需要进行完善 由黄腾飞负责企业自查风险管理子模块,要求为单元进行风险点的管理 由张梨贤 ...

  2. 学号:201621123032 《Java程序设计》第8周学习总结

    1:本周学习总结 2:书面作业 2.1:ArrayList代码分析 2.1.1:解释ArrayList的contains源代码 Contains方法调用indexof方法,如果元素为null,则循环比 ...

  3. C语言——第0次作业(二)

    1.翻阅邹欣老师的关于师生关系博客,并回答下列问题,每个问题的答案不少于500字: 1.最理想的师生关系是健身教练和学员的关系,在这种师生关系中你期望获得来自老师的哪些帮助? 在现代软件工程讲义 0 ...

  4. Flask 学习 十三 应用编程接口

    最近这些年,REST已经成为web services和APIs的标准架构,很多APP的架构基本上是使用RESTful的形式了. REST的六个特性: 客户端-服务器(Client-Server)服务器 ...

  5. 用js 获取url 参数 页面跳转 ? 后的参数

    记得之前在原来的公司写过这个东西,但是还是忘记怎么接住参数了,只知道怎么把id传过去! 问了身边的大佬 他首先推荐了我一个链接是别人写好的方法 附上链接地址:http://blog.csdn.net/ ...

  6. python基础学习篇章一

    一. 对Python的认识 1. Python的标准实现方式是将源代码的语句编译为字节码的形式,之后再将字节码解释出来.由于字节码是一种与平台无关的形式,字节码具有可移植性.但是Python没有将代码 ...

  7. python 字符串和字典

    一.字符串操作 name = "my name is \t {name} and i am {year} years old" 1.首字母大写 print(name.capital ...

  8. python+flask 分分钟完美解析阿里云日志

    拿到了自己阿里云服务器的日志,对其需要进行处理. class Read_Rizhi: def __init__(self,filename): self.filename=filename def o ...

  9. ELK学习总结(4-2)关于导入数据

    用REST API的_bulk来批量插入,可以达到5到10w条每秒 把数据写进json文件,然后再通过批处理,执行文件插入数据: 1.先定义一定格式的json文件,文件不能过大,过大会报错 2.后用c ...

  10. 阿里云API网关(3)快速入门(调用 API)

    网关指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl 网关控制台: https ...