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. [笔记] 使用frp从外网访问内网

    之前尝试过otunnel,也记录过使用方法,见[笔记] 使用otunnel从外网访问内网,但是用了几天发现还是不够稳定. 然后尝试frp,发现性能稳定,够用,将过程及配置分享在这里吧. 需求 内网机器 ...

  2. DES加密解密工具

    using System; using System.Text; using System.Security.Cryptography; using System.IO; namespace DESP ...

  3. Nginx动态添加模块 平滑升级

    已经安装好的Nginx动态添加模块 说明: 已经安装好的Nginx,需要添加一个未被编译安装的模块,需要怎么弄呢? 这里已安装第三方nginx-rtmp-module模块为例 nginx的模块是需要重 ...

  4. kindeditor-4.1.7

    <script src="~/Scripts/jquery-1.10.2.min.js" type="text/javascript"></s ...

  5. 蓝鲸-监控 排错思路 - 原理push - bkdata报错 - saas的日志

    1.现象和报错 .[10.253.124.21] paas_agent() paas_agent FATAL Exited too quickly (process log may have deta ...

  6. (转)使用 HTML5 WebSocket 构建实时 Web 应用

    HTML5 WebSocket 简介和实战演练 本文主要介绍了 HTML5 WebSocket 的原理以及它给实时 Web 开发带来的革命性的创新,并通过一个 WebSocket 服务器和客户端的案例 ...

  7. sqlalchemy链接数据库

    from sqlalchemy import create_engine HOSTNAME = '127.0.0.1' PORT = 3306 DATABASE = 'first_sqlalchemy ...

  8. Pandas时间序列和分组聚合

    #时间序列import pandas as pd import numpy as np # 生成一段时间范围 ''' 该函数主要用于生成一个固定频率的时间索引,在调用构造方法时,必须指定start.e ...

  9. Macaca环境搭建(三)----uirecorder Android录制

    一.安装Macaca-Android 命令窗口输入:npm i macaca-android -g 二.安装android-SDK 1.下载并安装ADT-bundle,官网下载地址我就不提供了,因为下 ...

  10. 如何使用JavaScript实现前端导入和导出excel文件

    一.SpreadJS 简介 SpreadJS 是一款基于 HTML5 的纯 JavaScript 电子表格和网格功能控件,以“高速低耗.纯前端.零依赖”为产品特色,可嵌入任何操作系统,同时满足 .NE ...