题目分析:

如果一个双连通分量是简单环,那么用polya原理计数循环移位即可。

如果一个双连通分量不是简单环,那么它必然可以两两互换,不信你可以证明一下相邻的可以互换。

如果一条边是桥,那么直接乘以k就行了。

代码:

 #include<bits/stdc++.h>
using namespace std; const int mod = ;
const int maxn = ; int n,m,k;
vector <int> g[maxn]; int fa[maxn],arr[maxn],dfn[maxn],bccnum,low[maxn],cl; vector <pair<int,int> > bcc[maxn];
vector <int> hhh[maxn]; void read(){
scanf("%d%d%d",&n,&m,&k);
for(register int i=;i<=m;i++){
int u,v; scanf("%d%d",&u,&v);
g[u].push_back(v); g[v].push_back(u);
}
} stack<int> sta;
void Tarjan(int now,int f){
fa[now] = f;
low[now] = dfn[now] = ++cl;
sta.push(now);
for(int i=;i<g[now].size();i++){
if(g[now][i] == f) continue;
if(dfn[g[now][i]] > dfn[now]) continue;
if(!dfn[g[now][i]]){
Tarjan(g[now][i],now);
low[now] = min(low[now],low[g[now][i]]);
}else{
low[now] = min(low[now],dfn[g[now][i]]);
hhh[now].push_back(g[now][i]);
}
}
if(f == || low[now] >= dfn[fa[now]]){
bccnum++;
while(true){
int k = sta.top();sta.pop();
arr[k] = ;
if(fa[k] == ) break;
bcc[bccnum].push_back(make_pair(k,fa[k]));
for(int i=;i<hhh[k].size();i++){
bcc[bccnum].push_back(make_pair(k,hhh[k][i]));
}
if(k == now) break;
}
if(bcc[bccnum].size() == ) bccnum--;
}
} int C[maxn*][maxn*]; int fast_pow(int now,int pw){
int ans = ,dt = now, bit = ;
while(bit <= pw){
if(bit & pw){ans =1ll*ans*dt%mod;}
dt = 1ll*dt*dt%mod; bit<<=;
}
return ans;
} int solve(int now){
int ans = ;
for(register int i=;i<=now;i++){
ans += fast_pow(k,__gcd(now,i));
ans %= mod;
}
ans = 1ll*ans*fast_pow(now,mod-)%mod;
return ans;
} int hap[maxn];
void work(){
for(register int i=;i<=n;i++){
if(arr[i]) continue;
Tarjan(i,);
}
C[][] = ;
for(register int i=;i<=;i++){
C[i][] = C[i][i] = ;
for(register int j=;j<i;j++){
C[i][j] = (C[i-][j] + C[i-][j-])%mod;
}
}
int ans = ;
for(register int i=;i<=bccnum;i++){
int flag = ;
for(register int j=;j<bcc[i].size();j++){
if(hap[bcc[i][j].first] && hap[bcc[i][j].second]) flag--;
hap[bcc[i][j].first]++; hap[bcc[i][j].second]++;
}
for(register int j=;j<bcc[i].size();j++){
hap[bcc[i][j].first]--; hap[bcc[i][j].second]--;
}
if(flag == || flag == ){
if(bcc[i].size() == ) ans = 1ll*ans*k%mod;
else ans = 1ll*ans*solve(bcc[i].size())%mod;
}else{
ans = 1ll*ans*C[bcc[i].size()+k-][k-]%mod;
}
}
printf("%d",ans);
} int main(){
read();
work();
return ;
}

AtcoderARC062F Painting Graphs with AtCoDeer 【双连通分量】【polya原理】的更多相关文章

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

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

  2. [Arc062] Painting Graphs with AtCoDeer

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

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

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

  4. HohoCoder 1184 : 连通性二·边的双连通分量(+原理证明)

    1184 : 连通性二·边的双连通分量 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在基本的网络搭建完成后,学校为了方便管理还需要对所有的服务器进行编组,网络所的老师 ...

  5. 【ARC062F】 Painting Graphs with AtCoDeer 点双连通分量+polya定理

    Description 给定一张N点M边的无向图,每条边要染一个编号在1到K的颜色. 你可以对一张染色了的图进行若干次操作,每次操作形如,在图中选择一个简单环(即不经过相同点的环),并且将其颜色逆时针 ...

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

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

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

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

  8. [atARC062F]Painting Graphs with AtCoDeer

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

  9. [ARC062F]Painting Graphs with AtCoDeer

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

随机推荐

  1. MySQL表结构变更,不可不知的Metadata Lock

    在线上进行DDL操作时,相对于其可能带来的系统负载,其实,我们最担心的还是MDL其可能导致的阻塞问题. 一旦DDL操作因获取不到MDL被阻塞,后续其它针对该表的其它操作都会被阻塞.典型如下,如阻塞稍久 ...

  2. 使用 OpenSSL 创建私有 CA:1 根证书

    OpenSSL 创建私有 CA 三部曲:使用 OpenSSL 创建私有 CA:1 根证书使用 OpenSSL 创建私有 CA:2 中间证书使用 OpenSSL 创建私有 CA:3 用户证书 OpenS ...

  3. Jenkins - SSH认证方式拉取Git代码

    1.本地生成密钥 [root@root ~] ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which ...

  4. IP核引发的关于定,浮点数的认识

    上面是一段关于CORDIC_IP测试文件,用于计算给定角度的sin值和cos值,关于数值表示规则在此不再重复,仅仅说明以下3点: 1  数采用原码,反码,补码,本身并没有正确与否之分(这一点很重要,我 ...

  5. iOS开发之一句代码检测APP版本的更新

    提示更新效果图如下,当然也是可以自定义类似与AlertView相似的自定义view,如京东.网易云音乐都是自定义了这种提示框的view.以下只展示,从App Store获取到app信息.并解析app信 ...

  6. [iOS]一行代码集成空白页面占位图(基于runtime+MJRefresh思想)

    2018年01月03日阅读 2472   [iOS]一行代码集成空白页面占位图(基于runtime+MJRefresh思想) LYEmptyView 此框架是本人在5,6个月前,公司启动新项目的时候, ...

  7. Tomcat Cluster

    Tomcat群集配置| Tomcat集群| MuleSofthttps://www.mulesoft.com/tcat/tomcat-cluster Tomcat Clustering - A Ste ...

  8. 【翻译】FluentValidation验证组件的使用

    由于本文是翻译,所以将原文原原本本的搬上来,大家看原文有什么不懂的也可以对照这里. 给出地址:https://fluentvalidation.net/ FluentValidation fluent ...

  9. Oracle 序列(sequence)

    序列(sequence) 是Oracle提供的用于生成一系列唯一数字的数据库对象.它会自动生成顺序递增或者递减的序列号,以实现自动提供唯一的主键值.序列可以在多用户并发环境中使用,并且可以为所有用户生 ...

  10. Latex常用

    插入罗马数字 \newcommand{\RNum}[1]{\uppercase\expandafter{\romannumeral #1\relax}} 然后在正文里面就可以用\RNum{}来添加罗马 ...