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种置换,其中当项链珠子数位奇数时,循环节的个 ...
随机推荐
- 基于Java实现的快速排序
简述 快速排序是一种排序执行效率很高的排序算法,它利用分治法来对待排序序列进行分治排序,它的思想主要是通过一趟排序将待排记录分隔成独立的两部分,其中的一部分比关键字小,后面一部分比关键字大,然后再对这 ...
- Kendo MVVM 数据绑定(十一) Value
Kendo MVVM 数据绑定(十一) Value Value 绑定可以把 ViewModel 的某个属性绑定到 DOM 元素或某个 UI 组件的 Value 属性.当用户修改 DOM 元素或 UI ...
- 两个页面实现mui轮播图与选项卡结合
index.html页面 <!DOCTYPE html><html><head> <meta charset="utf-8"> &l ...
- zblog忘记后台密码怎么办 官方解决方案
刚装的zblog还没开始研究,结果发现密码弄错了进不去后台,也是醉了 为节省时间,直接用官方方案,就是一个无密码进后台的文件.下载后把文件上传至网站根目录,然后直接访问后台修改密码 zblog密码找回 ...
- PHP 解决同一个IP不同端口号session冲突的问题
在项目的开发阶段,我们经常会遇到几个站点共用同一个IP用不同端口号区分的形式!但是,这样很容易导致一个问题,session冲突丢失!即两个站点具有相同的session变量,清除session的时候即全 ...
- Selenium3+webdriver学习笔记3(xpath方式元素定位)
#!/usr/bin/env python# -*- coding:utf-8 -*- from selenium import webdriver import time,os # about:ad ...
- ssh连接github连不上
连接github报端口22连接不上: 输入命令展示出ssh_config内容后: vim /etc/ssh/ssh_config 或者使用open /etc/ssh/ssh_config命令在文本编辑 ...
- MATLAB中容易忽略却经常遇到的小技巧总结
1 如何产生一个列向量相同的矩阵 例如,列向量x=[1;2;3],要产生矩阵A=[x,x,x],即[1,1,1;2,2,2;3,3,3]. A = repmat(x,1,n) 2 ...
- python_93_面向对象实例2
class Role: def __init__(self,name,role,weapon,life_value=100,money=15000): '构造函数:实例化时做一些类的初始化工作' se ...
- React脚手架less的安装
最近在用react.js 结合蚂蚁金服的 Ant Design Mobile 做一个单页面的应用程序,遇到了一个很棘手的问题——那就是 react脚手架不支持less,看了不少优秀博主如何在react ...