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种置换,其中当项链珠子数位奇数时,循环节的个 ...
随机推荐
- ES5数组遍历
reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值. array.reduce(function(total, currentValue, curren ...
- Mybatis find_in_set 子查询,替代 in
1. Mapper文件 2.dao层 3.生成Sql
- Vue.js + Webpack + ECMAScript 6 入门教程
Vue.js学习教程 1.Vue.js——60分钟快速入门 2.Vue.js——60分钟组件快速入门(上篇) 3.Vue.js——60分钟组件快速入门(下篇) 4.Vue.js——基于$.ajax实现 ...
- cmd_ping命令
ping命令是网络命令里的核心命令,同时也是黑客入侵的基础命令.下面和大家分享一下ping命令的基础知识和一般用法. 以ping百度公司域名为例,介绍ping命令相关内容. 一.ping命令基础知识 ...
- equals()方法详解
Java语言中equals()方法的使用可以说比较的频繁,但是如果轻视equals()方法,一些意想不到的错误就会产生.哈哈,说的有点严重了~ 先谈谈equals()方法的出身.equals()方法在 ...
- 【虚拟机-网关】如何在使用应用程序网关和 Nginx 的环境下实现强制 HTTPS 跳转
背景介绍 大家在使用 Nginx 部署网站时,实现 HTTP 到 HTTPS 的强制跳转是非常容易的事情,一般可以使用rewrite 命令或者使用返回自定义 301 页面的方法对 HTTP 请求进行 ...
- Python+selenium之测试报告(3)
较测试报告(2),该文章将测试报告和测试截图存放在随机变动的文件夹下面,去除了要存放在指定文件夹下面的限制. 注:遇到问题有: 1.创建由时间自动拼接的多级文件夹 2. import os impor ...
- github上fork原项目,如何将本地仓库代码更新到最新版本?
场景: 在github上fork原项目,项目组成员发起pull request提交了代码,这时自己在本地仓库该如何更新到最新代码? 操作方法如下: 方法一.从github上进行操作然后更新 登录自己的 ...
- JavaScript模板引擎的使用
为了将数据库中的一组记录转换成HTML输出到界面上,大家都采用哪些做法呢? 在WebForm时代我们经常使用datagrid.repeater,当MVC问世后我们开始直接在视图上编写C#循环语句,而现 ...
- xwork-conversion.properties 目前没有解决方案
它没法变成.xml 这意味着项目里就只能这样