当前位置: 首页 > news >正文

ARC062F Painting Graphs with AtCoDeer

给定一个 \(n\) 个点 \(m\) 条边的简单无向图 \(G\),你需要为每条边染 \(1\)\(k\) 中的一种颜色。

我们定义一次操作为,选择 \(G\) 中的一个简单环,将环上的边进行循环移动。

定义 \(G_1\)\(G_2\) 本质相同,当且仅当 \(G_1\) 能在若干次操作后与 \(G_2\) 相同。

求本质不同的涂色方案数量,对 \(10^9+7\) 取模。

\(1 \leq n \leq 50\)\(1 \leq m \leq 100\)\(1 \leq k \leq 100\)

考虑简单环上循环移动的性质,容易发现如下事实:

  • 若两个简单环有公共边,则其内部的边可以任意排列。

我们只需要实现交换两条边即可,你发现其实此时有两个小环和一个大环可以操作,这一步是容易构造方法的,虽然我不会就是了。

接下来我们就可以找到每个点双。

若点双中没有环,每条边都会产生 \(k\) 的贡献。

若点双恰好为一个环,等价于环染色,使用 Pólya 定理即可。

若点双包含 \(\geq 2\) 个环,则两种方案等价当且仅当每种颜色的出现次数相同,我们统计这个组合可以使用插板法。

结束了。

代码大概是东拼西凑的所以有点乱。

#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
using namespace std;
const long long mod=1000000007;
vector<int> G[60],dcc[60];
int low[60],dfn[60],seq,tot,root;
bool cut[60];
stack<int> st;
void tarjan(int u){low[u]=dfn[u]=++seq;if(u==root  &&  G[u].empty()){return ;}st.push(u);int child=0;for(int i=0;i<G[u].size();i++){int v=G[u][i];if(!dfn[v]){child++;tarjan(v);low[u]=min(low[u],low[v]);if(low[v]==dfn[u]){if(u!=root  ||  child>1){cut[u]=true;}tot++;while(true){int pre=st.top();st.pop();dcc[tot].push_back(pre);if(pre==v) break;}dcc[tot].push_back(u);}}else{low[u]=min(low[u],dfn[v]);}}
}
long long pow_mod(long long num1,long long num2=mod-2){num1=(num1%mod+mod)%mod;num2=(num2%(mod-1)+(mod-1))%(mod-1);long long num3=1;while(num2){if(num2&1){num3=num3*num1%mod;}num1=num1*num1%mod;num2>>=1;}return num3;
}
bool graph[60][60];
long long fact[210],invfact[210];
long long my_gcd(long long x,long long y){while(y){long long z=x%y;x=y;y=z;}return x;
}
int main(){fact[0]=invfact[0]=1;for(int i=1;i<=200;i++){fact[i]=fact[i-1]*i%mod;invfact[i]=invfact[i-1]*pow_mod(i)%mod;}int n,m;long long k;scanf("%d %d %lld",&n,&m,&k);for(int i=1;i<=m;i++){int u,v;scanf("%d %d",&u,&v);G[u].push_back(v);G[v].push_back(u);graph[u][v]=graph[v][u]=true;}for(int i=1;i<=n;i++){if(!dfn[i]){root=i;tarjan(i);}}long long ans=1;for(int i=1;i<=tot;i++){int cnt_1=0,cnt_2=0;for(int j=0;j<dcc[i].size();j++){cnt_1++;for(int k=j+1;k<dcc[i].size();k++){if(graph[dcc[i][j]][dcc[i][k]]){cnt_2++;}}}if(cnt_1>cnt_2){ans*=k;ans%=mod;}else if(cnt_1==cnt_2){long long pre=0;for(int j=0;j<cnt_1;j++){pre+=pow_mod(k,my_gcd(j,cnt_1));}ans*=pre*pow_mod(cnt_1)%mod;ans%=mod;}else{ans*=fact[cnt_2+k-1]*invfact[cnt_2]%mod*invfact[k-1]%mod;ans%=mod;}}printf("%lld",ans);return 0;
}
http://www.zskr.cn/news/177387.html

相关文章:

  • GitHub热门项目推荐:PyTorch-CUDA-v2.8开箱即用深度学习容器
  • SSH隧道转发可视化界面:远程调试PyTorch模型的新方法
  • 从本地到云端:迁移PyTorch项目使用CUDA加速推理
  • conda环境冲突怎么办?直接使用PyTorch-CUDA-v2.8纯净镜像
  • Java的包装类
  • CUDA安装头疼?PyTorch-CUDA镜像已自动完成所有配置
  • CUDA版本与PyTorch对应关系表:避免安装踩坑
  • PyTorch-CUDA-v2.8镜像支持ARM架构GPU服务器
  • 万维易源API与jmeter查询快递物流
  • http定义了几种不同的请求方法
  • 清华镜像源列表更新:PyTorch相关包下载地址大全
  • Docker Compose环境变量注入:动态配置PyTorch参数
  • 3个OpenTK最具价值的功能和应用场景
  • Matlab Simulink下的柔性直流输电系统四端网络无功补偿与电压稳定控制策略
  • AI初创团队必看:用PyTorch镜像快速构建MLOps流水线
  • 【计算机毕业设计案例】基于SpringBoot的办公管理系统设计与实现员工考勤工作任务安排(程序+文档+讲解+定制)
  • amesim一维仿真:汽车热管理、空调系统及整车热管理建模指南
  • 轻松运行CNN模型:PyTorch+CUDA镜像实测性能提升5倍
  • diskinfo SMART信息解读:判断SSD是否需要更换
  • springboot房屋租赁信息线上管理系统的设计与实现_7o5t2mu1
  • 【计算机毕业设计案例】基于java的动漫网站设计与实现基于springBoot的动漫分享系统的设计与实现(程序+文档+讲解+定制)
  • 【毕业设计】基于springBoot的动漫分享系统的设计与实现(源码+文档+远程调试,全bao定制等)
  • 无需手动配置!PyTorch-CUDA基础镜像支持多卡并行计算
  • 【视频】RK3576硬编解码库安装及使用;GStreamer测试插件详解
  • JiyuTrainer下载与集成:基于PyTorch的可视化训练工具探索
  • YOLOv5模型剪枝压缩:基于PyTorch的轻量化方案
  • 【视频】GStreamer+WebRTC(五):通过修改SDP改变webrtc数据流单双方向
  • Docker日志轮转配置:防止PyTorch容器日志占满磁盘
  • 科研绘图 | 基于云-TOPSIS法综合评价模型结构图
  • Jupyter Notebook魔法命令:%timeit测试PyTorch运算性能