1 条题解

  • 0
    @ 2026-6-25 21:57:37

    题目传送门

    题目解释

    给定两个数 nnkk,分别代表节点的个数和颜色的个数。求合法的染色方案,使得任何两个距离不大于 22 的不同节点所被染的颜色不同。ansans 需要对 109+710^{9}+7 取模。

    题目分析

    写在前面

    本题通过 dfs 做,所以每一次对于节点 kk,只考虑 kk 上面的节点对于 kk 的染色方案的影响。 在下面的分析中会出现数组:fakfa_{k} 表示 kk 节点的父亲。

    简化分析

    一条链

    显然,第一个节点的方案数为 kk,第二个节点的方案数为 (k1)(k-1),后面的节点的染色方案为 (k2)(k-2)。这个链的染色方案数为:ans=k×(k1)×(k2)n2ans=k\times (k-1)\times (k-2)^{n-2}

    节点 fakfa_{k} 第一个计算的节点

    这个节点 kk 不用考虑 fakfa_{k} 的其他儿子,所以方案数还是 (k2)(k-2),当然,如果 fakfa_{k} 是树的根节点,方案数即为 (k1)(k-1)

    节点 fakfa_{k} 然后计算的节点

    显然, kk 的方案数为 (k2x)(k-2-x)xx 代表在 kk 前面计算过的 fakfa_{k} 的子节点。(因为与 kk 节点距离不大于2的节点除了 fakfa_{k}fafakfa_{fa_{k}},只有 fakfa_{k} 的其他子节点。)

    所以

    这棵树和它的子树都可以通过类似的方法用 dfs 递归下去,所以本题是一道简简单单的递归题。

    参考代码

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int MAXN=1e5+5;
    const int mod=1e9+7;
    int n,k;
    int ans=1;
    int head[MAXN],tot;
    struct edge{
    	int to,nxt;
    }e[MAXN<<1];
    void edgeadd(int u,int v){
    	e[++tot].nxt=head[u];
    	e[tot].to=v;
    	head[u]=tot;
    }
    int cnt[MAXN];
    void dfs(int u,int fa,int sum){
    	ans=(ans*max(0ll,k-sum)%mod)%mod;
    	cnt[u]++;
    	for(int i=head[u];i;i=e[i].nxt){
    		int v=e[i].to;
    		if(v!=fa){
    			cnt[v]++;
    			dfs(v,u,cnt[u]);
    			cnt[u]++;
    		}
    	}
    }
    signed main(){
    	cin.tie(0);
    	cout.tie(0);
    	ios::sync_with_stdio(false);
    	cin>>n>>k;
    	for(int i=1,u,v;i<n;i++){
    		cin>>u>>v;
    		edgeadd(u,v);
    		edgeadd(v,u);
    	}
    	dfs(1,0,0);
    	cout<<ans;
    }
    
    • 1

    信息

    ID
    11697
    时间
    2000ms
    内存
    1024MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者