G.coloring tree BFS计数

题目:给你n(<=5000)个节点的一颗树 你有K(<=5000)种颜色 你可以给每一个节点染一种颜色

总共有Kn种染色方法 在一种染色方法中 定义colorness为每一对相同颜色节点距离中的最短距离

问colorness为D时 有多少种染色方案 结果%mod

解:我们先求出>=D的方案数再减去>=D+1的方案数就是==D的方案数

现在问题变为>=X的方案数 可以看成对于任意一个节点,所有和它距离小于d的节点,不能和它有相同的颜色

然后我们随便找个根节点开始bfs染色,怎么染色呢?
我们考虑根节点,它有k种颜色可以染,我们给根染了一种颜色之后,所有和根在距离<d的点,可以被染的颜色都会少一种,
然后我们bfs对所有的节点都这样做,然后我们最后把每个点可以染的颜色种类数乘起来,就是我们需要的答案了。
上述思路代码实现应该是很简单的,因为数据范围只有5000,我们可以对每个点都dfs一次,求出所有点之间的距离。然后计算的时候每次都把距离<d的所有点可选颜色都-1。
代码实现不是主要部分,重点是为什么按照bfs的顺序去做可以保证答案正确呢?
这里就要考虑一个问题了。假如我们有两种颜色,每个节点不能和距离<=1的点有相同的颜色,我们要怎么做呢?
比如我们有三个节点
1->2->3
如果我们不按照bfs顺序来染色
1有两种染色方案,3也有两种染色方案,这样一看,2就没有染色方案了,最后乘出来的答案就会为0。这是为什么呢?
我们发现1和3可以选取的颜色有重复,然后作用到2这个节点就会出问题。
那么  为什么bfs能保证答案正确呢?
我画了很久的图。。发现了一个性质。。
如果我们按照bfs的顺序来选择颜色计算方案数的话,已经选过颜色的和当前节点距离在d以内的节点,一定两两距离都在d以内
就是说,当前节点距离d以内的已经选择过颜色的节点在选择颜色种类的时候一定会互相考虑到彼此节点,如果我们用dfs,就保证不了这个性质了。
感谢牛客多校群的大佬帮我完成了这个证明
当前bfs到的节点 和其它(bfs走过的&&到当前节点距离<d)的点,两两之间距离<d的证明如下:
dis(u,v)=dis(u,x)+dis(v,x)-*dis(lca(u,v),x)
当前枚举点为x,u,v是任意点,lca是对于x为根
设u为深度比较低的那个点,
dis(u,x)-dis(lca(u,v),x)是大于等于dis(v,lca(u,v))的
然后代进去就能发现dis(u,v)<=dis(v,x)的
/*Huyyt*/
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-;
const int dir[][] = {{, }, {, }, {, -}, { -, }, {, }, {, -}, { -, -}, { -, }};
const int mod = 1e9 + , gakki = + + + + 1e9;
const int MAXN = 1e5 + , MAXM = 1e5 + , MAXQ = , INF = 1e9;
const ll LLINF = (1LL << );
int to[MAXM << ], nxt[MAXM << ], Head[MAXN], tot = ;
inline void addedge(int u, int v)
{
if (u == v)
{
return ;
}
to[++tot] = v;
nxt[tot] = Head[u];
Head[u] = tot;
}
template <typename T> inline void read(T&x)
{
char cu = getchar();
x = ;
bool fla = ;
while (!isdigit(cu))
{
if (cu == '-')
{
fla = ;
}
cu = getchar();
}
while (isdigit(cu))
{
x = x * + cu - '', cu = getchar();
}
if (fla)
{
x = -x;
}
}
ll n, k, d;
ll dis[][];
ll val[];
void dfs(int s, int now, int pre)
{
for (int v, i = Head[now]; i; i = nxt[i])
{
v = to[i];
if (v == pre)
{
continue;
}
dis[s][v] = dis[s][now] + ;
dfs(s, v, now);
}
}
ll get_ans(ll d)
{
queue<ll> q;
q.push();
for (int i = ; i <= n; i++)
{
val[i] = k;
}
ll ans = ;
while (!q.empty())
{
ll i = q.front();
q.pop();
ll res = ;
for (int j = ; j <= n; j++)
{
if (i != j)
{
val[j] -= dis[i][j] < d;
}
}
if(val[i]<=)
return ;
ans=ans*val[i]%mod;
for(int v,j=Head[i];j;j=nxt[j])
{
v=to[j];
if(dis[][i]+==dis[][v])
{
q.push(v);
}
}
}
return ans;
}
int main()
{
ios_base::sync_with_stdio();
cin.tie(); read(n), read(k), read(d);
int u, v;
for (int i = ; i < n; i++)
{
read(u), read(v);
addedge(u, v), addedge(v, u);
}
for (int i = ; i <= n; i++)
{
dfs(i, i, -);
}
ll anser = (get_ans(d) - get_ans(d + ) + mod) % mod;
printf("%lld\n", anser);
return ;
}

uestc summer training #9 牛客第三场 BFS计数的更多相关文章

  1. 牛客第三场多校 E Sort String

    链接:https://www.nowcoder.com/acm/contest/141/E来源:牛客网 Eddy likes to play with string which is a sequen ...

  2. 牛客第三场多校 H Diff-prime Pairs

    链接:https://www.nowcoder.com/acm/contest/141/H来源:牛客网 Eddy has solved lots of problem involving calcul ...

  3. uestc summer training #4 牛客第一场

    A dp[i][j][k]可以n3地做 但是正解是找把问题转化为一个两点不相交路径 最终答案为C(n+m, n)2-C(n+m, m-1)C(n+m,n-1) B 把题目的矩阵看成无向图的邻接矩阵 这 ...

  4. Shuffle Cards(牛客第三场+splay)

    题目: 题意:将1~n的数进行m次操作,每次操作将第pi位到pi+si-1位的数字移到第一位,求最后的排列. 思路:现在还没不会写splay,在知道这是splay模板题后找了一波别人的模板,虽然过了, ...

  5. PACM Team(牛客第三场多校赛+dp+卡内存+打印路径)

    题目链接(貌似未报名的不能进去):https://www.nowcoder.com/acm/contest/141/A 题目: 题意:背包题意,并打印路径. 思路:正常背包思路,不过五维的dp很容易爆 ...

  6. 牛客第三场 J LRU management

    起初看到这道题的时候,草草就放过去了,开了另一道题,结果开题不顺利,总是感觉差一点就可以做出来,以至于一直到最后都没能看这道题qaq 题意:类似于操作系统上讲的LRU算法,有两个操作,0操作代表访问其 ...

  7. 最长相同01数的子串(map搞搞)--牛客第三场 -- Crazy Binary String

    题意: 如题. 或者用我的数组分治也可以,就是有点愚蠢. //#include <bits/stdc++.h> #include <map> #include <iost ...

  8. 平面割线平分点(构造)--牛客第三场-- Magic Line

    题意: 给你n个点的坐标,让你给出两个点,这两个点的连线可以平分这些点. 思路: 先按y的大小排序,在按x的小排序,再搞一下就行了.如下图: #include <bits/stdc++.h> ...

  9. 牛客第五场多校 J plan 思维

    链接:https://www.nowcoder.com/acm/contest/143/J来源:牛客网 There are n students going to travel. And hotel ...

随机推荐

  1. .pkl文件是什么?python

    对于.pkl文件,我是在接触 SMPL模型的时候用到的.SMPL的开源项目包里,有model文件夹,打开有两个.pkl文件.然后,找到了一个说的相对比较详细的网址.https://jingyan.ba ...

  2. 【ABAP系列】【第五篇】SAP ABAP7.50 之用户接口

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列][第五篇]SAP ABAP7.5 ...

  3. Linux 使用中history 默认记录数不够用了?

    1.默认情况下,系统能保存1000条的历史命令. #echo $HISTSIZE   2.那么1000条不够用,该怎么办呢? #vi /etc/profile 修改HISTSIZE=1000 > ...

  4. web题

    @php绕过https://www.cnblogs.com/leixiao-/p/9786496.html @step1:F12 step2:抓包 @任何url  http://118.25.14.4 ...

  5. AI 资源帖

    https://github.com/mnielsen/neural-networks-and-deep-learning openCV笔记 https://blog.csdn.net/qq_2689 ...

  6. c++ string详解 assign

    assign方法可以理解为先将原字符串清空,然后赋予新的值作替换. 返回类型为 string类型的引用.其常用的重载也有下列几种: a. string& assign ( const stri ...

  7. [转帖]【JDK和Open JDK】平常使用的JDK和Open JDK有什么区别

    https://www.cnblogs.com/sxdcgaq8080/p/7487369.html 其实不同的 openjdk的版本也不一样. atlassian说AdoptOpenJDK我们测试充 ...

  8. [转帖]Windows 下如何配置Oracle ASM???

    Windows 下如何配置Oracle ASM??? candon123关注10人评论16725人阅读2011-02-09 21:40:57   本篇介绍了如何在windows下创建裸设备,并创建AS ...

  9. P1004方格取数

    这是提高组得一道动态规划题,也是学习y氏思考法的第一道题. 题意为给定一个矩阵,里面存有一些数,你从左上角开始走到右下角,另一个人从右下角开始走到左上角,使得两个人取数之和最大,当然一个数只可以取走一 ...

  10. %300为0的个数(牛客第四场)-- number

    题意: 给你一串数,问你如题. 思路: 我不是这样的作法,从后往前,先取00,再算%3==0的个数,往前推的时候有递推关系: #define IOS ios_base::sync_with_stdio ...