LA 7056 Colorful Toy Polya定理
题意:
平面上给出一个\(N\)个点\(M\)条边的无向图,要用\(C\)种颜色去给每个顶点染色。
如果一种染色方案可以旋转得到另一种染色方案,那么说明这两种染色方案是等价的。
求所有染色方案数 \(mod \: 10^9+7\)
分析:
这种等价类计数的问题可以用Polya定理来解决。
首先这个图形要想能旋转,本身必须中心对称,即旋转以后的顶点和边要和原图完全重合,一一对应。
事实上,旋转的角度只能是\(90^{\circ}\)的整数倍。
因为给出来的点都是整点,求出来的对称中心的坐标也都是有理数。如果再旋转更小的角度的话(比如\(60^{\circ}\)),就一定会出现无理数的坐标,所以这是不可能的。
所以只会有一下三种情况:
- 图本身不对称,置换群只有一个恒等置换
- 图是中心对称,置换群有两个置换:恒等置换 和 逆时针旋转\(180^{\circ}\)
- 图不仅是中心对称,而且可以旋转\(90^{\circ}\),则置换群有四个置换:恒等置换 逆时针旋转\(90^{\circ}\) 逆时针旋转\(180^{\circ}\) 和 逆时针旋转\(270^{\circ}\)
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <map>
#define MP make_pair
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
const int maxn = 50 + 10;
const double eps = 1e-8;
const LL MOD = 1000000007;
void add_mod(LL& a, LL b) {
a += b; if(a >= MOD) a -= MOD;
}
LL pow_mod(LL a, int n) {
LL ans = 1LL;
while(n) {
if(n & 1) ans = ans * a % MOD;
a = a * a % MOD;
n >>= 1;
}
return ans;
}
LL Inverse(LL a) { return pow_mod(a, MOD - 2); }
int dcmp(double x) {
if(fabs(x) < eps) return 0;
return x < 0 ? -1 : 1;
}
struct Point
{
double x, y;
Point(double x = 0, double y = 0):x(x), y(y) {}
void read() { scanf("%lf%lf", &x, &y); }
};
typedef Point Vector;
Point operator + (const Point& A, const Point& B) {
return Point(A.x + B.x, A.y + B.y);
}
Point operator - (const Point& A, const Point& B) {
return Point(A.x - B.x, A.y - B.y);
}
Point operator * (const Point& A, double p) {
return Point(A.x * p, A.y * p);
}
Point operator / (const Point& A, double p) {
return Point(A.x / p, A.y / p);
}
bool operator == (const Point& A, const Point& B) {
return dcmp(A.x - B.x) == 0 && dcmp(A.y - B.y) == 0;
}
int n, m, c;
Point p[maxn], center;
bool G[maxn][maxn];
PII edges[maxn * maxn];
Point Rotate(Point P, int n) {
if(n == 0) return P;
Vector v = P - center;
if(n == 1) return center + Vector(-v.y, v.x);
if(n == 2) return center + Vector(-v.x, -v.y);
if(n == 3) return center + Vector(v.y, -v.x);
}
int Findit(Point q) {
for(int i = 1; i <= n; i++)
if(p[i] == q) return i;
return 0;
}
int t[maxn];
bool vis[maxn];
bool RotateGraph(int x) {
for(int i = 1; i <= n; i++) {
t[i] = Findit(Rotate(p[i], x));
if(t[i] == 0) return false;
}
for(int i = 0; i < m; i++) {
int u = edges[i].first, v = edges[i].second;
if(!G[t[u]][t[v]]) return false;
}
return true;
}
int Cycle() {
memset(vis, false, sizeof(vis));
int ans = 0;
for(int i = 1; i <= n; i++) if(!vis[i]) {
ans++;
vis[i] = true;
for(int s = t[i]; s != i; s = t[s]) {
vis[s] = true;
}
}
return ans;
}
int main() {
//freopen("7056.txt", "r", stdin);
LL inv_2 = Inverse(2), inv_4 = Inverse(4);
int T; scanf("%d", &T);
while(T--) {
scanf("%d%d%d", &n, &m, &c);
center = Point(0, 0);
for(int i = 1; i <= n; i++) {
p[i].read();
center = center + p[i];
}
center = center / n;
memset(G, false, sizeof(G));
for(int u, v, i = 0; i < m; i++) {
scanf("%d%d", &u, &v);
edges[i] = MP(u, v);
G[u][v] = G[v][u] = true;
}
LL ans = pow_mod(c, n) % MOD;
if(!RotateGraph(2)) { printf("%lld\n", ans); continue; }
int k = Cycle();
add_mod(ans, pow_mod(c, k));
if(!RotateGraph(1)) {
ans = ans * inv_2 % MOD;
printf("%lld\n", ans);
continue;
}
k = Cycle();
add_mod(ans, (pow_mod(c, k) * 2) % MOD);
ans = ans * inv_4 % MOD;
printf("%lld\n", ans);
}
return 0;
}
LA 7056 Colorful Toy Polya定理的更多相关文章
- 【转】Polya定理
转自:http://endlesscount.blog.163.com/blog/static/82119787201221324524202/ Polya定理 首先记Sn为有前n个正整数组成的集合, ...
- 【群论】polya定理
对Polya定理的个人认识 我们先来看一道经典题目: He's Circles(SGU 294) 有一个长度为N的环,上面写着“X”和“E”,问本质不同的环有多少个(不 ...
- [wikioi2926][AHOI2002]黑白瓷砖(Polya定理)
小可可在课余的时候受美术老师的委派从事一项漆绘瓷砖的任务.首先把n(n+1)/2块正六边形瓷砖拼成三角形的形状,右图给出了n=3时拼成的“瓷砖三角形”.然后把每一块瓷砖漆成纯白色或者纯黑色,而且每块瓷 ...
- HDU 3923 Invoker(polya定理+逆元)
Invoker Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 122768/62768 K (Java/Others)Total Su ...
- Polya定理
http://www.cnblogs.com/wenruo/p/5304698.html 先看 Polya定理,Burnside引理回忆一下基础知识.总结的很棒. 一个置换就是集合到自身的一个双射,置 ...
- POJ 2409 Let it Bead(Polya定理)
点我看题目 题意 :给你c种颜色的n个珠子,问你可以组成多少种形式. 思路 :polya定理的应用,与1286差不多一样,代码一改就可以交....POJ 1286题解 #include <std ...
- POJ 1286 Necklace of Beads(Polya定理)
点我看题目 题意 :给你3个颜色的n个珠子,能组成多少不同形式的项链. 思路 :这个题分类就是polya定理,这个定理看起来真的是很麻烦啊T_T.......看了有个人写的不错: Polya定理: ( ...
- 百练_2409 Let it Bead(Polya定理)
描述 "Let it Bead" company is located upstairs at 700 Cannery Row in Monterey, CA. As you ca ...
- polya定理小结
polya的精髓就在与对循环节的寻找,其中常遇到的问题就是项链染色类问题. 当项链旋转时有n种置换,循环节的个数分别是gcd(n, i); 当项链翻转时有n种置换,其中当项链珠子数位奇数时,循环节的个 ...
随机推荐
- JVM类加载机制二
类加载器与双亲委派模型 类加载器 类加载的操作不是有虚拟机完成的,而是由类加载器完成的,这样可以让程序定义决定加载哪个类. 类加载器的分类: 从虚拟机的角度有两种加载器,一种是启动类加载器Bootst ...
- 整合mybatis分页插件及通用接口测试出现问题
严重: Servlet.service() for servlet [springmvc] in context with path [/mavenprj] threw exception [Requ ...
- 桉树IAAS云架构(转载)
您可在 IaaS 云中建立和管理混合多虚拟机集群环境,并将现有 vSphere™. ESX™.ESXi™.KVM 和 XEN 虚拟环境作为 AWS 兼容 Eucalyptus桉树混合云管理.现在 Eu ...
- javascript简单计算器实践
参考部分资料,编写一个简单的计算器案例,虽然完成了正常需求,但是也有不满之处,待后续实力提升后再来补充,先把不足之处列出: 1:本来打算只要打开页面,计算器的输入框会显示一个默认为0的状态,但是在输入 ...
- uvm_reg_block——寄存器模型(七)
这是寄存器模型的顶层 //------------------------------------------------------------------------ // Class: uvm_ ...
- 宿主机Windows访问虚拟机Linux文件(二)
上一篇文章中详细讲述FTP服务(基于文件传输协议的服务),本文则介绍另一种能够实现此功能Telnet(Telecommunications network 远程登陆)服务.本文介绍的telnet我常用 ...
- Java Object Model(一)
Java作为OOP语言,抽象性不言而喻.如果需要深入了解Java语言的实现机制,则不得不对Java语言中基础的概念有清晰的了解.今天是我在cnblog上写博客的第一天,希望今天的博客可以是我成为未来& ...
- Securityonion介绍
下载地址 https://github.com/Security-Onion-Solutions/security-onion/blob/master/Verify_ISO.md ...
- ArcGis server发布地图服务
ArcGIS server发布服务: 首先修改地图文档属性中的关联默认数据库 最后使用分享将地图服务发布到server上,是地图服务可以使用: 注意一定要勾选 Feature Access选项 fea ...
- 2018.5.9 Oracle数据库查询命令
0.查询所有数据(最简单,但是时间很久) select * from emp; Result: EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ----- - ...