zoukankan      html  css  js  c++  java
  • 2018牛客网暑假ACM多校训练赛(第三场)G Coloring Tree 计数,bfs

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round3-G.html

    题目传送门 - 2018牛客多校赛第三场 G

    题意

      给定一个 $n$ 个节点的树,有 $k$ 种颜色。

      现在让你给每一个节点都染上一种颜色,总共有 $k^n$ 种方法。

      现在问,在所有染色方案中,使得相同颜色点对之间的最短距离为 $D$ 的有多少种方案。

      答案对于 $10^9+7$ 取模。

      $n,k,dleq 5000$

    题解

      首先我们来算一下相同颜色点对之间的最短距离不小于 $D$ 的情况。

      我们考虑 bfs 。

      对于当前节点,我们找出已经访问过的节点中与当前节点的距离小于 $D$ 的节点。

      由于我们是 bfs 的,可以证明找出的这些节点任意两个之间的距离一定小于 $D$ 。所以这些节点的颜色互不相同。

      记这些节点的总个数为 $cnt$ ,则当前节点可以染的颜色种数为 $k-cnt$ 。

      那么答案就累乘一下就可以了。

      时间复杂度 $O(n^2)$ 。

      但是我们要求的是等于 $D$ 的情况。

      怎么做?

      减掉大于 $D$ 的情况种数即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=5005,mod=1e9+7;
    struct Gragh{
    	static const int M=N*2;
    	int cnt,y[M],nxt[M],fst[N];
    	void clear(){
    		cnt=0;
    		memset(fst,0,sizeof fst);
    	}
    	void add(int a,int b){
    		y[++cnt]=b,nxt[cnt]=fst[a],fst[a]=cnt;
    	}
    }g;
    int n,k,D;
    int vis[N],Q[N],head,tail;
    int cnt1,cnt2;
    void dfs(int x,int pre,int d){
    	if (d>D+1)
    		return;
    	if (d<=D)
    		cnt1++;
    	cnt2++;
    	for (int i=g.fst[x];i;i=g.nxt[i])
    		if (g.y[i]!=pre&&vis[g.y[i]])
    			dfs(g.y[i],x,d+1);
    }
    int main(){
    	scanf("%d%d%d",&n,&k,&D),D--;
    	g.clear();
    	for (int i=1,a,b;i<n;i++){
    		scanf("%d%d",&a,&b);
    		g.add(a,b);
    		g.add(b,a);
    	}
    	memset(vis,0,sizeof vis);
    	head=tail=0;
    	Q[++tail]=1;
    	int ans1=1,ans2=1;
    	while (head<tail){
    		int x=Q[++head];
    		vis[x]=1,cnt1=cnt2=-1;
    		dfs(x,0,0);
    		cnt1=max(k-cnt1,0),cnt2=max(k-cnt2,0);
    		ans1=1LL*ans1*cnt1%mod;
    		ans2=1LL*ans2*cnt2%mod;
    		for (int i=g.fst[x];i;i=g.nxt[i])
    			if (!vis[g.y[i]])
    				Q[++tail]=g.y[i];
    	}
    	printf("%d",(ans1-ans2+mod)%mod);
    	return 0;
    }
    

      

  • 相关阅读:
    cin、cout、cerr、clog------c++ Primer Plus
    c++ 用new后delete,而继续输出指针后果 new/new[]/delete/delete[]区别
    c++类
    c++内联 inline
    c++ 委托构造函数
    c++ explicit
    activti表结构
    工作流设计
    问题解决
    grep 命令
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round3-G.html
Copyright © 2011-2022 走看看