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. Centos安装php高版本

    安装 1.检查当前是否有安装php  rpm -qa|grep php 如果有安装PHP,那么请先删除这些安装包:  yum remove php* 2.安装php源 Centos 5 安装php源: ...

  2. keil:C语言里面调用汇编程序

    C语言直观,汇编效率高,C里面嵌入汇编是很好的选择. 路径大概如图: mian.c是我的C语言程序,Func.s是汇编程序. 主要是Init_1这个函数的实现在汇编文件里面,使用汇编实现的. 首先在C ...

  3. Win7 IE11 F2无法切换版本

    Win7 IE11 F2无法切换版本 http://www.microsoft.com/zh-cn/download/confirmation.aspx?id=45154 选择操作系统对应的版本 ht ...

  4. Oracle11g-BBED安装

    oracle 11g中缺bbed包 下载地址: https://pan.baidu.com/s/19DVvIajarDjnynILNwQDWQ 密码:tmqt 1.BBED的安装 1.上传(sbbdp ...

  5. Apache Shiro 权限框架

    分享一个视屏教程集合 http://www.tudou.com/home/konghao/item 1.Shiro Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码 ...

  6. Libevent使用例子,从简单到复杂

    转载请注明出处:http://blog.csdn.net/luotuo44/article/details/39670221 本文从简单到复杂,展示如何使用libevent.网上的许多例子都是只有服务 ...

  7. 解决Axis2在webservice中遇到特殊字符的无法传输的缺陷(<CDATA>数据类型)

    在使用Axis2进行soa webservice开发时,遇到类似以下的错误信息: com.ctc.wstx.sw.BaseStreamWriter.writeCharacters(BaseStream ...

  8. C# XML 操作

    1 xml文件格式 <?xml version="1.0" encoding="utf-8"?> <userInfo> <user ...

  9. Objects & Class

    [Objects & Class] 1.定义一个类. 上述代码中,numberOfSides是实例变量,simpleDescription也是实例方法. 2.创建实例,使用实例. 3.init ...

  10. java基础之JDBC二:原生代码基础应用

    JDBC的基础应用CURD: 增删改 public void noQuery() { Connection conn = null; Statement stat = null; try { //注册 ...