ABC133 E Virus Tree 2 树形遍历+染色

本文探讨了E-VirusTree2问题,即在给定的无向树中,为每个节点分配颜色,确保相邻节点颜色不同。文章通过深度优先搜索(DFS)策略,详细阐述了如何计算所有合法着色方案的数量,适用于大规模问题(节点数量可达10^5)。代码实现部分展示了如何利用递归和模运算来高效解决问题。

题目:E - Virus Tree 2

给定一个含 K K K个节点的无向树,给每个顶点赋上 [ 1 , K ] [1,K] [1,K]一整数(染上一种颜色)。并且,若两个顶点距离 ≤ 2 \le2 2,那么两顶点值不同(颜色不同)。

1 ≤ N , K ≤ 1 0 5 1\le N,K\le 10^5 1N,K105

考察

首先无向树的根可以随意设定,我们就从第1个开始查找(邻接表)。根的颜色肯定是K种可用。我们固定好根的颜色后,用DFS向下探索遍历所有的枝及叶。赋值的时候,我们可以考虑以下两点

  • 根的颜色数为 K K K
  • 固定顶点值和父级节点值,其所有子节点的赋值方案为 k − 2 P s _{k-2}P_s k2Ps,其中 s s s为子节点数量

代码实现

// some macroes and includes
//---------------------
#define MAXN 100005
#define MOD 1000000007
//---------------------

ll n,k;
vector<int> G[MAXN];
ll ret=1;

ll modmult(ll a , ll b ){
  return ( (a%MOD) * (b%MOD)  ) %MOD;
  }

void solve(ll lastId,ll curId,ll depth){
  	
	if(ret==0) {ret=0;return;}
	ll temp=depth==0 ? k:1;
	ll id=k-min(depth+1,ll(2));
	REP(i,G[curId].size()){
		if(G[curId][i] == lastId) continue;
		solve( curId , G[curId][i] , depth+1);
		temp = modmult(temp,max(id--,ll(0)));
	}
	ret = modmult(ret,temp);
	//cout<<ret<<endl;
}

int main(){
  	cin>>n>>k;
  	REP(i,n-1) {int a,b;cin>>a>>b;G[a].PB(b);G[b].PB(a);}
  	solve(-1,1,0);
	cout << ret <<endl;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值