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种置换,其中当项链珠子数位奇数时,循环节的个 ...
随机推荐
- C# 加密、解密函数
#region ========加密======== /// <summary> /// 加密 /// </summary> /// <param name=" ...
- GNUPG
PGP (Pretty Good Privacy) 是由 Phil Zimmermann 于 1991 开发的一个用于数据加密和数字签名的程序,由于被广泛应用以至于后来形成一个开放的标准 OpenPG ...
- dao层写展示自己需要注意的问题
写dao层时一定要把 News news=new News(); 写在while循环内,是每循环一次,new出一个对象
- hive中select中DISTINCT的技巧和使用
hive中select中DISTINCT的技巧和使用 单表的唯一查询用:distinct 多表的唯一查询用:group by 在使用MySQL时,有时需要查询出某个字段不重复的记录,虽然mysql提供 ...
- 【转】Java Cipher类 DES算法(加密与解密)
Java Cipher类 DES算法(加密与解密) 1.加密解密类 import java.security.*; import javax.crypto.*; import java.io.*; / ...
- cpp 计算程序运行时间的两种方法
1. #include <time.h> time_t begin_t = clock(); // to do time_t finish_t = clock(); cout<< ...
- (一)我的Javascript系列:Javascript的面向对象旅程(上)
今宵酒醒何处,杨柳岸,晓风残月 导引 我的JavaScript系列文章是我自己对JavaScript语言的感悟所撰写的系列文章.现在还没有写完.目前一共出了下面的系列: (三)我的JavaScript ...
- Windows基础环境_安装配置教程(Windows7 64、JDK1.8、Android SDK23.0、TortoiseSVN 1.9.5)
Windows基础环境_安装配置教程(Windows7 64.JDK1.8.Android SDK23.0.TortoiseSVN 1.9.5) 安装包版本 1) JDK版本包 地址: htt ...
- 挂sqlserver计划,系统自动分配拣货任务
USE [P2WMS_WH43] GO /****** Object: StoredProcedure [dbo].[sp_fru_CalcAllocatePickData] Script Date: ...
- 加载动画插件spin.js的使用随笔
背景: 在请求后台的“漫长”等待过程中,为了提升用户体验,需要一个类似 的加载动画效果,让用户明确现在处于请求过程中,而不是机子down掉或者网站死了 静态demo(未与后台交互): HTML代码如 ...