牛客多校3 G Coloring Tree (DFS+BFS)

题意:
给你一个由n个节点n-1条边组成的树,之后你可以在每个节点上面染颜色,定义一个颜色度,表示的是相同颜色最近的距离是多少,现在想问你颜色度为d的染色方案数是多少。
思路
相同颜色最近的距离是D,换句话说就是一个节点在距离D内都不能有相同的颜色。
那么我们定义F(D)表示的是颜色度大于等于D的时候的方案数,那么的话,颜色度等于D的方案数其实就是 F(D+1) - F(D),知道这个之后我们就可以求F(D)了,具体怎么求F(D),我们广搜所有节点,对于我们当前广搜的节点我们深搜看他的子树下面有多少个已经被染色的节点,如果有一个我们就让他减一,之后方案数相乘就是答案上代码把:
代码

#include 
#define mod 1000000007
using namespace std;
const int maxn = 5000 + 10;
vector<int>V[maxn];
queue<int>que;
int s,t,n,k,d,vis[maxn];
void dfs(int u,int fa,int de)
{
    if(vis[u])
    {
       // printf("%d  %d\n",de,d);
        if(de < d) s--;
        if(de <= d) t--;
    }
    for(int i = 0 ; i < V[u].size() ; i++)
    {
        int v = V[u][i];
        if(v == fa) continue;
        dfs(v,u,de+1);
    }
}
int main()
{
    scanf("%d%d%d",&n,&k,&d);
    for(int i = 0 ,u,v; i < n -1 ; i++)
    {
        scanf("%d%d",&u,&v);
        V[u].push_back(v);
        V[v].push_back(u);
    }
    que.push(1);
    long long ans1 = 1 , ans2 = 1;
    while(!que.empty())
    {
        int u = que.front();
        que.pop();
        s = k , t = k;
        dfs(u,0,0);
        //printf("%d %d\n",s,t);
        ans1 = ans1 * s % mod;
        ans2 = ans2 * t % mod;
        vis[u] = 1;
        for(int i = 0 ; i < V[u].size() ; i++)
        {
            int v = V[u][i];
            if(vis[v]) continue;
            que.push(v);
        }
    }
   // printf("%lld %lld\n",ans1,ans2);
    printf("%lld\n",(ans1-ans2+mod)%mod);
    while(1);
}

你可能感兴趣的:(搜索)