Description

给定一张N点M边的无向图,每条边要染一个编号在1到K的颜色。

你可以对一张染色了的图进行若干次操作,每次操作形如,在图中选择一个简单环(即不经过相同点的环),并且将其颜色逆时针旋转一个单位。

形式的说,假设你选择的环上的边按顺序依次是e1, e2, ... ,ek,那么经过一次操作后ei mod n+1的颜色会变成操作前ei的颜色。

两种染色方案被认为是本质相同的,当且仅当其中一种染色后的图经过若干次操作后可以变成另一种染色后的图。

问有多少本质不同的染色方案,输出对10^9+7取模。

Input

第一行三个正整数N M K

接下来M行每行两个正整数表示图中的一条边。

Output

输出一行一个非负整数表示答案。

Sample Input

Sample Input 1
4 4 2
1 2
2 3
3 1
3 4 Sample Input 2
5 2 3
1 2
4 5 Sample Input 3
11 12 48
3 1
8 2
4 9
5 4
1 6
2 9
8 3
10 8
4 10
8 6
11 7
1 8

Sample Output

Sample Output 1
8 Sample Output 2
9 Sample Output 3
569519295

HINT

1≤N≤50

1≤M, K≤100

Sol

每个点双联通分量的贡献是独立的,我们用tarjan找出每个点双联通分量,然后分类讨论:

如果只是一条不属于双联通分量的边,那么贡献是k;

如果是个简单环,那么就转化成项链计数问题,这个要用polya定理来解决,具体地:

\(res=\sum_{i=1}^{n}gcd(i,n)\)

如果是好多环拼一起的,可以发现分量中任何边都能通过旋转交换,那么我们枚举每个颜色有\(x_i\)个,这就转化成不定方程解个数,用隔板法解决,即\(C_{n+k-1}^{k-1}\)。

显然第一种和第二种在tarjan中会当成一种处理,而且他们也是等价的。第三种在遇到\(low[to[i]]>=dfn[x]\)的时候判一下,如果有个点被边的出点经过了多次,说明是情况三,然后找出边总数然后计算即可。

细节:1.反向边记得也要打vis标记 2.当前边也要退栈以及进行计算贡献 3.邻接表下标不要从0开始,如果从0开始的话请把栈数组赋值为-1。

Code

#include <bits/stdc++.h>
#define ll long long
#define P 1000000007ll
using namespace std;
int x,y,n,m,k,I,hed[51],nex[201],to[201],low[201],dfn[201],vis[51],top,s[201],cnt=1,use[201];
ll ans=1,fac[201],mi[201],ifa[201],inv[201];
void add(int x,int y){to[++cnt]=y;nex[cnt]=hed[x];hed[x]=cnt;}
void dfs(int x)
{
dfn[x]=low[x]=++I;
for(int i=hed[x];i!=-1;i=nex[i]) if(!use[i]&&!use[i^1])
{
s[++top]=i;use[i]=use[i^1]=1;
if(!dfn[to[i]])
{
dfs(to[i]);low[x]=min(low[x],low[to[i]]);
if(low[to[i]]>=dfn[x])
{
bool cir=1;int tot=0;ll res=0;
for(int j=top;s[j+1]!=i;j--,tot++) if(vis[to[s[j]]]) cir=0;else vis[to[s[j]]]=1;
if(cir){for(int j=0;j<tot;j++) res=(res+mi[__gcd(tot,j)])%P;res=res*inv[tot]%P;}
else res=fac[tot+k-1]*ifa[k-1]%P*ifa[tot]%P;
ans=ans*res%P;
for(;s[top+1]!=i;top--) vis[to[s[top]]]=0;
}
}
else low[x]=min(low[x],dfn[to[i]]);
}
}
int main()
{
scanf("%d%d%d",&n,&m,&k);mi[0]=fac[0]=fac[1]=ifa[0]=ifa[1]=inv[1]=1;mi[1]=k;memset(hed,-1,sizeof(hed));
for(int i=2;i<=m+k;i++) mi[i]=mi[i-1]*k%P,fac[i]=i*fac[i-1]%P,inv[i]=(P-P/i)*inv[P%i]%P,ifa[i]=ifa[i-1]*inv[i]%P;
for(int i=1;i<=m;i++) scanf("%d%d",&x,&y),add(x,y),add(y,x);
for(int i=1;i<=n;i++) if(!dfn[i]) dfs(i);
printf("%lld\n",ans);
}

【ARC062F】 Painting Graphs with AtCoDeer 点双连通分量+polya定理的更多相关文章

  1. AtcoderARC062F Painting Graphs with AtCoDeer 【双连通分量】【polya原理】

    题目分析: 如果一个双连通分量是简单环,那么用polya原理计数循环移位即可. 如果一个双连通分量不是简单环,那么它必然可以两两互换,不信你可以证明一下相邻的可以互换. 如果一条边是桥,那么直接乘以k ...

  2. [ARC062F]Painting Graphs with AtCoDeer

    题意:一个无向图,用$k$种不同的颜色给每条边染色,问能染出多少种不同的图,如果两张图能通过循环移位环边使得颜色相同,那么这两张图被认为是相同的 数学太差伤不起啊...补了一下Burnside定理的证 ...

  3. [Arc062] Painting Graphs with AtCoDeer

    [Arc062] Painting Graphs with AtCoDeer Description 给定一张N点M边的无向图,每条边要染一个编号在1到K的颜色.你可以对一张染色了的图进行若干次操作, ...

  4. ARC 062 F - Painting Graphs with AtCoDeer 割点 割边 不动点 burnside引理

    LINK:Painting Graphs with AtCoDeer 看英文题面果然有点吃不消 一些细节会被忽略掉. 问每条边都要被染色 且一个环上边的颜色可以旋转. 用c种颜色有多少本质不同的方法. ...

  5. 【AtCoder】ARC062F - AtCoDeerくんとグラフ色塗り / Painting Graphs with AtCoDeer

    题解 考虑一个点双(因为是简单环),如果没有环(两点一线),那么乘上K 如果有一个环,那么用polya定理,每个置换圈有gcd(i,n)个循环节 如果有两个及以上的环,任何一种置换都合法,那么只和每个 ...

  6. [atARC062F]Painting Graphs with AtCoDeer

    求出点双后缩点,对于点双之间,显然不存在简单环,即每一个简单环一定在一个点双内部,换言之即每一个点双可以独立的考虑,然后将结果相乘 (对于点双之间的边任意染色,即若有$s$条边,还会有$k^{s}$的 ...

  7. ARC062 - F. Painting Graphs with AtCoDeer (Polya+点双联通分量)

    似乎好久都没写博客了....赶快来补一篇 题意 给你一个 \(n\) 个点 , 没有重边和自环的图 . 有 \(m\) 条边 , 每条边可以染 \(1 \to k\) 中的一种颜色 . 对于任意一个简 ...

  8. ARC062F AtCoDeerくんとグラフ色塗り / Painting Graphs with AtCoDeer Burnside 引理

    题目传送门 https://atcoder.jp/contests/arc062/tasks/arc062_d 题解 首先对整张图做 Tarjan 点双. 对于一个点双,如果是由一条边构成的,那么很显 ...

  9. 2018.09.20 atcoder Painting Graphs with AtCoDeer(tarjan+polya)

    传送门 一道思维题. 如果没有环那么对答案有k的贡献. 如果恰为一个环,可以用polya求贡献. 如果是一个有多个环重叠的双联通的话,直接转化为组合数问题(可以证明只要每种颜色被选取的次数相同一定可以 ...

随机推荐

  1. python's twenty-sixth day for me 模块

    configparser 模块: 该模块适用于配置文件的格式与windows ini文件类似,可以包含一个或多个节(section),每个节可以有多个参数(键 = 值). 创建文件: # 创建文件 i ...

  2. 去掉字符串中的html标签

    public static string removeHtml(string html) { System.Text.RegularExpressions.Regex regex1 = new Sys ...

  3. Linux的基本指令--目录和文件和文件属性和文件用户组

    目录和文件 一 .  ls:列出目录的内容,未给出目录名或是文件名时,就显示当前目录的信息. -a 列出隐藏文件,文件中以”.”开头的均为隐藏文件,如:~/.bashrc  -l 列出文件的详细信息 ...

  4. Properties & Method

    [Properties] 1.lazy property,通过@property来定义, lazy property的属性直到使用的时候才初始化: 2.Computed Properties: 2.对 ...

  5. zookeeper伪集群的搭建

    由于公司服务器数量的限制,我们往往没有那么多的服务器用来搭建zookeeper的集群,所以产生了伪集群的搭建,也就是将多个zookeeper搭建在同一台机器上. 准备工作: 1,一台服务器,我们这里用 ...

  6. Java “hello word” 第一天

    //新建包和类 //java是包,c#是命名空间package test1;/** * 需求:练习一个hello word * 思路: * 1.定义一个类,因为java程序都是以类的形式存在的,类的形 ...

  7. apt-get update 时的问题 W:Failed to fetch gzip:/var/lib/apt/lists/partial...解决办法

    http://askubuntu.com/questions/149454/upgrade-from-11-04-to-11-10-getting-wfailed-to-fetch-gzip 这个问题 ...

  8. SHELL读取 ini 格式文件做配置文件

    ini文件格式一般都是由节.键.值三部分组成 格式: [第一节 ] 第一个键 = 值 第二个键 = 第二个值 [第二节 ] 第一个键 = val1,val2,val3 例子: [COM] KINGGO ...

  9. R语言安装包,切换镜像

    source("http://bioconductor.org/biocLite.R") options(BioC_mirror="http://mirrors.ustc ...

  10. (转)ASP.NET MVC4+EasyUI+EntityFrameWork权限管理系统——数据库的设计(一)

    原文地址:http://www.cnblogs.com/cmsdn/p/3371576.html 快一年没写博客了,这段时间感觉好迷茫,写点博客,记录一下自己的成长过程,希望对大家也有帮助 先上图 一 ...