首页 > 其他分享 >[ABC294Ex] K-Coloring

[ABC294Ex] K-Coloring

时间:2023-03-20 17:00:03浏览次数:32  
标签:方案 Coloring 颜色 int 钦定 35 返祖 ABC294Ex

考虑 dfs 后搞出 dfs 树,考虑若干返祖边有限制,那么,我们一个朴素的想法是枚举这些有被返祖边搞到的点的颜色,但这样最坏是 \(O(K^n)\) 的。

但显然一条返祖边在钦定完一个端点的颜色之后,另一端的颜色便可以不用钦定,因此指数可以减小一点。

那么我们可以钦定每个返祖边深度小的点的颜色,但是直接钦定是 \(O(K^t)\) 的,\(t\) 是返祖边深度小的点的集合大小。考虑我们并不关心其真正的颜色是什么,因此这东西可以集合划分后再给每个集合分配颜色。

那么这样子,你就有若干点的颜色钦定了,记钦定的颜色数量为 \(c\),但整棵树的染色显然不可能只用 \(c\) 种,但其他的颜色我们都是未钦定的,考虑另分一类给这些颜色。

记 \(f(x,i)\) 表示 \(x\) 为第 \(i\) 种颜色的时候,其子树内染色的方案数。

考虑转移,对于树边的转移是朴素的。

对于返祖边的话,由于我们已经钦定了深度小的点的颜色,那么当前点的颜色也必须与其相同,不相同的方案数直接没了即可。

注意之后方案数应乘上对该集合划分分配颜色的方案数。

不重不漏的证明:考虑一种合法的染色方案,显然会被在钦定其返祖点的颜色时钦定到这种方案,且只钦定到一次。假如一种方案被钦定了两次的话。若颜色划分的集合不同,那么两种染色方案一定不同。若颜色划分的集合相同,但对集合分配的颜色方案不同,则两种染色方案一定不同。则关键,在于转移。而我们的转移并不会重算同一种方案,因为其都是子树各自考虑而又独立合并的。所以一种方案不会被钦定多次。

#include <bits/stdc++.h>
#define int long long
#define pb push_back
using namespace std;
const int mod=998244353;
struct edge {
	int nex,to;
}e[70];
int f[35][35],n,m,K,dfn[35],tot,otot,o[35],rt,col[35],fa[35],hea[35],cnt=1;

void add_edge(int x,int y) {
	e[++cnt].nex=hea[x]; e[cnt].to=y; hea[x]=cnt;
}

void dfs0(int x,int pre) {
	dfn[x]=++tot;
	for(int i=hea[x];i;i=e[i].nex) {
		if((i==(pre^1))) continue ;
		int y=e[i].to;
		if(!dfn[y]) dfs0(y,i);
		else if(dfn[y]<=dfn[x]) {
			o[++otot]=y;
		}
	}
}

bool vis[35];
int C;
void dp(int x,int pre) {
	if(!col[x]) {
		for(int i=0;i<=C;i++) f[x][i]=1;
	} else {
		for(int i=0;i<=C;i++) f[x][i]=0;
		f[x][col[x]]=1;
	}
	vis[x]=1;
//	cout<<x<<" "<<ff<<" in\n";
	for(int j=hea[x];j;j=e[j].nex) {
		if((j==(pre^1))) continue ;
		int y=e[j].to;
		if(!vis[y]) {
			dp(y,j);
			int qwq=f[y][0]*(K-C-1)%mod;
			for(int i=1;i<=C;i++) qwq=(qwq+f[y][i])%mod;
			f[x][0]=f[x][0]*qwq%mod;
			qwq=0;
			for(int i=1;i<=C;i++) qwq=(qwq+f[y][i])%mod;
			for(int i=1;i<=C;i++) {
				int qaq=(f[y][0]*(K-C)%mod+(qwq-f[y][i]+mod)%mod)%mod;
				f[x][i]=f[x][i]*qaq%mod;
			}
		} else if(dfn[y]<=dfn[x]) {
			for(int i=0;i<=C;i++) {
				if(i==col[y]) f[x][i]=0;
			}
		}
	}
//	cout<<": "<<x<<" -> "<<col[x]<<'\n';
//	for(int i=0;i<=C;i++) cout<<f[x][i]<<' ';
//	cout<<'\n';
}

int nwans,ans;
void dfs(int x,int c) {
	if(c>K) return ;
	if(x==otot+1) {
		for(int i=1;i<=n;i++) vis[i]=0;
		C=c; dp(rt,0);
		int res=f[rt][0]*(K-C)%mod;
		for(int i=1;i<=C;i++) res=(res+f[rt][i])%mod;
		for(int i=K-C+1;i<=K;i++) res=res*i%mod;
		nwans=(nwans+res)%mod;
		return ;
	}
	for(int i=1;i<=c;i++) col[o[x]]=i,dfs(x+1,c);
	col[o[x]]=c+1; dfs(x+1,c+1);	
}

signed main() {
	cin.tie(0); ios::sync_with_stdio(false);
	cin>>n>>m>>K;
	for(int i=1;i<=m;i++) {
		int x,y; cin>>x>>y; add_edge(x,y); add_edge(y,x);
	}
	ans=1;
	for(int i=1;i<=n;i++) {
		if(!dfn[i]) {
			rt=i; nwans=0; otot=0;
			dfs0(rt,0);
			sort(o+1,o+1+otot);
			if(otot) otot=unique(o+1,o+1+otot)-o-1;
//			for(int j=1;j<=otot;j++) cout<<o[j]<<' ';
//			cout<<'\n';
			dfs(1,0);
//			cout<<nwans<<'\n';
			ans=ans*nwans%mod;
		}
	}
	ans=(ans%mod+mod)%mod; cout<<ans;
	return 0;
}

标签:方案,Coloring,颜色,int,钦定,35,返祖,ABC294Ex
From: https://www.cnblogs.com/xugangfan/p/17236869.html

相关文章

  • 41. CF-Graph Coloring
    链接先考虑怎样的图可以染色或者不能染色。容易发现,1和3不能相邻,它们其实是等价的。那么能染色的必要条件就是所有的子图都是二分图。此外,每个二分图都取左部或者右部......
  • Educational Codeforces Round 143 (Rated for Div. 2) D - Triangle Coloring
    lucas定理求大组合数取模板子#include<bits/stdc++.h>#definefifirst#definesesecond#defineiostd::ios::sync_with_stdio(false)usingnamespacestd;typede......
  • D. Triangle Coloring
    https://codeforces.com/contest/1795/problem/D#include<iostream>#include<cstring>#include<algorithm>#include<string>#include<cmath>usingnamespacest......
  • D. Triangle Coloring (组合数)
    #pragmaGCCoptimize("O3")#pragmaGCCoptimize("O2")#pragmaGCCoptimize("O1")#include<bits/stdc++.h>typedeflonglongll;typedefunsignedlonglong......
  • Educational Codeforces Round 72 (Rated for Div. 2)D. Coloring Edges 神仙规律
    D.ColoringEdgestimelimitpertest1secondmemorylimitpertest256megabytesinputstandardinputoutputstandardoutputYouaregivenadirectedgraphw......
  • [LeetCode] 1145. Binary Tree Coloring Game
    Twoplayersplayaturnbasedgameonabinarytree.Wearegiventhe root ofthisbinarytree,andthenumberofnodes n inthetree. n isodd,andeach......
  • 「CF1792F2」Graph Coloring (Hard Version)
    代码点这里看题目。有一个\(n\)​个点的无向有标号完全图,你需要给每一条边染上红色或者蓝色。对于一个点集\(S\)(\(|S|\ge2\)),如果仅保留红边时\(S\)中的点是连通......
  • 题解 ARC115C【ℕ Coloring】
    显然\(A_1,A_2,A_4,A_8,\cdots\)必须互不相同,因此最大的数一定不小于\(\lfloor\log_2n\rfloor+1\),猜想可以取到\(\lfloor\log_2n\rfloor+1\)。构造\(A_i=\lfloor\log......
  • Coloring
    题目链接题目描述:Cirno_9bakahasapapertapewith\(n\)cellsinarowonit.Ashethinksthattheblankpapertapeistoodull,hewantstopaintthesecel......
  • CF1774B-Coloring
    挺有意思的一个思维题题面翻译Cirno_9baka的纸条上有\(n\)个格子,他觉得空白的纸条看着有点无趣,于是想在纸条的格子上涂上\(m\)种颜色。同时,他认为第\(i\)种颜色必......