Description


m≤n+5,k,n≤105m\leq n+5,k,n\leq10^5m≤n+5,k,n≤105

Solution 1

这个图只有5条返祖边所以才能做,

先把所有有返祖边的点拿出来,(姑且叫做返祖点)
自然地,考虑容斥,枚举一条返祖边的两个点是否同色,以及返祖边点之间的染色情况,
枚举后DP计算,设fx,if_{x,i}fx,i​表示点x染颜色i时的方案数,注意颜色0表示其他颜色,即没有被枚举的颜色,

因为有6条返祖边,所以染色情况最多877种(贝尔数),每次DP至少需要O(n)时间,过不了考虑优化,

显然的,所有度数为1的点都可以删掉,他们对ans的贡献恒为(K-1),
删完以后再把链缩一下就是返祖点构成的虚树了,

缩链简单,像矩阵乘法那样弄就好了,

这样每次DP的复杂度就很小了,直接在虚树上跑即可,

复杂度:O(k3n+2Bkk)O(k^3n+2B_kk)O(k3n+2Bk​k)
(前面的预处理+后面的枚举及DP)

Solution 2

先转化一下,
原图的每条边都有两个值(a,b),分别表示如果两个点同色的贡献和不同色的贡献,
对于一种染色方案,答案为所有边的贡献乘起来,
显然的,对于原图,每条边的值为(0,1),

考虑缩点,
显然的叶子可以直接缩点,他们对ans的贡献恒为(K-1),

对于度数为2的点,可以通过以下方式缩掉:
设点uuu数为2,它连向的两个点为v1,v2v_1,v_2v1​,v2​,边(u,v1)(u,v_1)(u,v1​)的值为(a1,b1)(a_1,b_1)(a1​,b1​),边(u,v2)(u,v_2)(u,v2​)的值为(a2,b2)(a_2,b_2)(a2​,b2​),
删去点uuu以及其连出去的边,
添加边(v1,v2)(v_1,v_2)(v1​,v2​),其值为(a1a2+b1b2(K−1),a1b2+b1a2+b1b2(K−2))(a_1a_2+b_1b_2(K-1),a_1b_2+b_1a_2+b_1b_2(K-2))(a1​a2​+b1​b2​(K−1),a1​b2​+b1​a2​+b1​b2​(K−2))

这样不停的缩点,最后最多只会剩下10个点15条边,
这么小暴力即可,跑个状压DP子集转移之类的即可

Code

#include <cstdio>
#include <algorithm>
#include <iostream>
#define fo(i,a,b) for(int i=a;i<=b;++i)
#define fod(i,a,b) for(int i=a;i>=b;--i)
#define efo(i,q) for(int i=A[q];i;i=B[i][0])
#define min(q,w) ((q)>(w)?(w):(q))
#define max(q,w) ((q)<(w)?(w):(q))
using namespace std;
typedef long long LL;
const int N=100500,mo=1e9+7;
int read(int &n)
{char ch=' ';int q=0,w=1;for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());if(ch=='-')w=-1,ch=getchar();for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;
}
int m,n,K,root;
LL ans;
int B[2*N][3],A[N],B0=1,Bv[N];
int Fa[N],Fav[N],Jp[N],d[N];
int HU[10][2],HU0;
int z[N];
int g[7][N][7][7],gmx;
LL f[N][9];
LL jc[N],jcn[N];
int MOJ(LL &q,int w){return (q+=w)>=mo?q-=mo:q;}
int MOJ(int &q,int w){return (q+=w)>=mo?q-=mo:q;}
LL ksm(LL q,int w)
{LL ans=1;for(;w;w>>=1,q=q*q%mo)if(w&1)ans=ans*q%mo;return ans;
}
LL P(int m,int n){return jc[m]*jcn[m-n]%mo;}
void link(int q,int w)
{++Bv[q],++Bv[w];B[++B0][0]=A[q],A[q]=B0,B[B0][1]=w;B[++B0][0]=A[w],A[w]=B0,B[B0][1]=q;
}
void dfsh(int q,int fa)
{z[q]=1;efo(i,q)if(!B[i][2]&&B[i][1]!=fa){if(!z[B[i][1]])dfsh(B[i][1],q);else B[i][2]=B[i^1][2]=1,HU[++HU0][0]=q,HU[HU0][1]=B[i][1];}
}
int dfsf(int q,int fa,int c)
{Fav[q]=max(0,c-1);gmx=max(gmx,Fav[q]);Jp[q]=q;Fa[q]=fa;f[q][0]=1;if(B[B[A[q]][0]][0])c=0;efo(i,q)if(!B[i][2]&&B[i][1]!=fa){Jp[q]=dfsf(B[i][1],q,c+1);f[q][0]=f[q][0]*f[B[i][1]][0]%mo*(K-1LL)%mo;}return (B[B[A[q]][0]][0]||!fa)?(Jp[q]=q):Jp[q];
}
void dfs(int q,int fa,int cnt)
{int Q=q;q=Jp[q];fo(i,0,cnt)f[q][i]=1;efo(i,q)if(!B[i][2]&&B[i][1]!=Fa[q]){dfs(B[i][1],q,cnt);LL t=f[B[i][1]][0]*(K-cnt-1)%mo;fo(j,1,cnt)MOJ(t,f[B[i][1]][j]);f[q][0]=f[q][0]*(t)%mo;MOJ(t,f[B[i][1]][0]);fo(j,1,cnt)f[q][j]=f[q][j]*(t-f[B[i][1]][j])%mo;}if(z[q]){if(z[q]<=cnt){fo(i,0,cnt)if(i!=z[q])f[q][i]=0;}else fo(i,1,cnt)f[q][i]=0;}if(Fav[q]){fo(i,0,cnt)fo(j,0,cnt)f[0][i]=(f[0][i]+f[q][j]*g[cnt][Fav[q]][i][j])%mo;fo(i,0,cnt)f[Q][i]=f[0][i],f[0][i]=0;}
}
void ss(int q,int w,int e)
{if(q>HU0){if(!w)return;w=min(w,K-1);dfs(root,0,w);f[root][0]=f[root][0]*(K-w)%mo;fo(j,1,w)MOJ(f[root][0],f[root][j]);f[root][0]=f[root][0]*P(K,w)%mo;if(e&1)ans=(ans-f[root][0])%mo;else ans=(ans+f[root][0])%mo;return;}ss(q+1,w,e);++e;if(z[HU[q][0]]&&!z[HU[q][1]]){z[HU[q][1]]=z[HU[q][0]];ss(q+1,w,e);z[HU[q][1]]=0;return;}if(z[HU[q][1]]&&!z[HU[q][0]]){z[HU[q][0]]=z[HU[q][1]];ss(q+1,w,e);z[HU[q][0]]=0;return;}if(z[HU[q][0]]&&z[HU[q][1]]){if(z[HU[q][0]]==z[HU[q][1]])ss(q+1,w,e);return;}if(w<K)z[HU[q][0]]=z[HU[q][1]]=w+1,ss(q+1,w+1,e);fo(i,1,w)z[HU[q][0]]=z[HU[q][1]]=i,ss(q+1,w,e);z[HU[q][0]]=z[HU[q][1]]=0;
}
int main()
{freopen("color.in","r",stdin);freopen("color.out","w",stdout);int q,w;read(n),read(m),read(K);if(n==m+1)return printf("%lld\n",K*ksm(K-1,n-1)%mo),0;jc[0]=1;fo(i,1,K)jc[i]=jc[i-1]*i%mo;jcn[K]=ksm(jc[K],mo-2);fod(i,K-1,0)jcn[i]=jcn[i+1]*(i+1LL)%mo;fo(i,1,m)read(q),read(w),link(q,w);dfsh(1,0);fo(i,1,n)if(Bv[i]==1)d[++d[0]]=i;LL Ansc=1;for(;d[0];){q=d[d[0]];--d[0];z[q]=0;Ansc=Ansc*(K-1LL)%mo;efo(i,q)if((--Bv[B[i][1]])==1)d[++d[0]]=B[i][1];}fo(I,1,n)if(z[I]){for(int i=A[I],i1=0;i;i=B[i][0])if(!z[B[i][1]]){if(i1)B[i1][0]=B[i][0];else A[I]=B[i][0];}else i1=i;}fo(i,1,n)if(z[i]){root=i;break;}fo(i,0,n)z[i]=0;dfsf(root,0,0);ans=f[root][0]*K%mo;fo(I,1,min(K-1,HU0)){fo(i,0,I)g[I][0][i][i]=1;fo(i,1,gmx){fo(k,0,I)g[I][i][0][k]=(LL)g[I][i-1][0][k]*(K-I-1LL)%mo;fo(j,1,I)fo(k,0,I)MOJ(g[I][i][0][k],g[I][i-1][j][k]);fo(j,1,I)fo(k,0,I)g[I][i][j][k]=((LL)g[I][i][0][k]+g[I][i-1][0][k]-g[I][i-1][j][k])%mo;}}ss(1,0,0);ans=ans*Ansc%mo;printf("%lld\n",(ans+mo)%mo);return 0;
}

【JZOJ 6079】【GDOI2019模拟2019.3.23】染色问题相关推荐

  1. [jzoj 6093] [GDOI2019模拟2019.3.30] 星辰大海 解题报告 (半平面交)

    题目链接: https://jzoj.net/senior/#contest/show/2686/2 题目: 题解: 说实话这题调试差不多花了我十小时,不过总算借着这道题大概了解了计算几何的基础知识 ...

  2. JZOJ 6030. 【GDOI2019模拟2019.2.25】白白的

    Description Input Output Sample Input 4 3 6 0 10 1 1 2 1 0 1 2 Sample Output 1 1 0 Data Constraint S ...

  3. [JZOJ6075]【GDOI2019模拟2019.3.20】桥【DP】【线段树】

    Description N,M<=100000,S,T<=1e9 Solution 首先可以感受一下,我们把街道看成一行,那么只有给出的2n个点的纵坐标是有用的,于是我们可以将坐标离散化至 ...

  4. [JZOJ6093]【GDOI2019模拟2019.3.30】星辰大海【计算几何】【半平面交】

    Description 给出平面上n个点,其中1号点是可以移动的,但是移动的范围不能改变任意三个点所成的角的状态([0,π),[π,π],(π,2π][0,\pi),[\pi,\pi],(\pi,2\ ...

  5. jzoj6384. 【NOIP2019模拟2019.10.23】珂学家

    Description Input Output 输出共 行,每行一个非负整数表示答案. Sample Input 2 1 1 2 3 2 1 3 5 Sample Output 4 只能选用试剂1 ...

  6. gmoj 6087. 【GDOI2019模拟2019.3.26】获取名额 题解

    题目 https://gmoj.net/senior/#main/show/6087 题解 发现 ans=1−∏i=lr(1−aix)ans=1-\prod_{i=l}^r \left(1-\frac ...

  7. JZOJ6384【NOIP2019模拟2019.10.23】珂学家

    珂学家 题目描述: 输入: 输出: 输出共mmm行,每行一个非负整数表示答案. 这道题看到是一个区间,便想到了数据结构之类的东西. 但是呢它好像不带修.所以初步判断这是个离线的题目. 再仔细观察发现, ...

  8. 2019/2/23研究日志

    今天我们进行了第一次实践操作. 由于直接制作一个磁悬浮电子器件对于初步接触电子电工的我们来说要求太高,我们觉得循序渐进,经过试验和经验积累,逐步掌握电子电工知识,才有可能完成磁悬浮的设计和尝试制作.于 ...

  9. 训练日志 2019.1.23

    好几天没写训练日记了... 最近几天题出的不多,大部分时间都在补题... 今天做了两道模版题,一道最大团的,现学的 Bron-Kerbosch 算法,一道树形 DP 的题,最后时间不够了没交上... ...

最新文章

  1. 进程间通信:同步双工管道
  2. 消息队列怎么保证消息有没有重复消费(幂等性)?
  3. C#中DataGrid控件的基本使用
  4. idea中maven导入jar包
  5. 一篇总结的很好的Spring data jpa 文章,里面包含多种查询方式,可以结合api使用
  6. Spring Boot Web Slice测试–示例
  7. python 3.9 发布计划_Python 3.9.0 beta4 发布
  8. libcap-ng库旨在使具有posix功能的编程比传统的libcap库容易得多
  9. javaweb简单的登录增删改查系统_国产化之路统信UOS /Nginx /Asp.Net Core+ EF Core 3.1/达梦DM8实现简单增删改查操作...
  10. Qt 5 如何修改打包好的应用程序图标
  11. ATL 工程下添加右击菜单
  12. 开发利器--JSONVIEW插件 网页json数据直接转换
  13. Windows下安装JanusGraph(踩坑记录)
  14. adobe怎么统计字数_pdf文件怎么快速统计字数?
  15. Mac - 当前位置打开终端
  16. Troubleshooting: WAITED TOO LONG FOR A ROW CACHE ENQUEUE LOCK!
  17. 自制“营销号视频生成器”
  18. css计时动画,纯CSS实现倒计时动画
  19. MFC Windows程序设计学习笔记--文件和串行化
  20. 个人总结:Mysql知识图谱

热门文章

  1. XDU Problem 1037 - 智破机枪阵
  2. phpstudy运行php文件
  3. 用Python编写微信小游戏“跳一跳”的运行脚本
  4. H3CSE路由-BGP增强配置(二)
  5. 从头开始学算法:考研机试题练习(C/C++)–STL使用
  6. docker启动streamsets
  7. 那些程序员们后知后觉的职涯经验
  8. C语言如何实现动态数组?
  9. 【VS2019编辑器第一行默认添加:#define _CRT_SECURE_NO_WARNINGS 1\使用scanf函数报错 解决方案\创建源文件第一行不出现#define _CRT_SECURE】
  10. 使用php mcrypt加密解密