原题链接:

Kingdom Division

  1. 由于树的层次可能很深,所以这里不能使用递归版的DFS。我使用了BFS。
  2. BFS确定各结点的父结点和它的孩子数。
  3. 用逆拓扑排序确定结点的计算顺序。
  4. same[u][] 表示u结点颜色为0孩子结点颜色全为1时组合数。 diff[u][] 表示u结点颜色为0时可行组合数。本结点颜色为0,子结点颜色为1,孙结点颜色全为0是无效组合。反之亦然。由于这里颜色0、1相互对称, same[u][]=same[u][]; diff[u][]=diff[u][]; 。
  5. 为排除无效组合,计算 diff[u][] 时没有乘以 same[u][] 。
  6. 本结点为0,孩子结点全为1,是无效组合,因此 diff[u][] 最后还要减去 same[u][] 。
#include <cmath>
#include <cstdio>
#include <cassert>
#include <vector>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int MOD = 1e9+;
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int n = ; assert( == scanf("%d", &n));
vector<vector<int>> adjList(n + );
for(int i = ; i < n - ; i++){
int u, v; assert( == scanf("%d %d", &u, &v));
adjList[u].push_back(v);
adjList[v].push_back(u);
}
vector<vector<long long>> diff(n + , vector<long long>(, ));
vector<vector<long long>> same(n + , vector<long long>(, ));
vector<int> parent(n + , );
vector<int> child_cnt(n + , );
queue<int> traversal_array;
vector<bool> visited(n + , false);
traversal_array.push();
visited[] = true;
while(!traversal_array.empty()){
int tmp = traversal_array.front();
traversal_array.pop();
for(auto vit: adjList[tmp]){
if(!visited[vit]){
visited[vit] = true;
child_cnt[tmp]++;
parent[vit] = tmp;
traversal_array.push(vit);
}
}
} for(int c_i = ; c_i <= n; c_i++){
if(!child_cnt[c_i]){
traversal_array.push(c_i);
}
} while(!traversal_array.empty()){
int tmp = traversal_array.front();
traversal_array.pop();
child_cnt[parent[tmp]]--;
if(child_cnt[parent[tmp]] == ){
traversal_array.push(parent[tmp]);
}
for(auto vit: adjList[tmp]){
if(vit != parent[tmp]){
same[tmp][] = same[tmp][] * diff[vit][] % MOD;
same[tmp][] = same[tmp][] * diff[vit][] % MOD;
}
}
for(auto vit: adjList[tmp]){
if(vit != parent[tmp]){
diff[tmp][] = diff[tmp][] * (diff[vit][] + diff[vit][] + same[vit][]) % MOD;
diff[tmp][] = diff[tmp][] * (diff[vit][] + diff[vit][] + same[vit][]) % MOD;
}
}
diff[tmp][] = (diff[tmp][] - same[tmp][] + MOD) % MOD;
diff[tmp][] = (diff[tmp][] - same[tmp][] + MOD) % MOD;
}
printf("%lld\n", (diff[][] + diff[][])%MOD);
return ;
}

最新文章

  1. java工程或web工程项目上出现红色感叹号
  2. JavaScript闭包(一)——实现
  3. 基于SPSS的美国老年夏季运动会运动员数据分析
  4. Podfile升级后的影响
  5. iostart命令
  6. java理论基础学习一
  7. RAID
  8. Linux mkisofs 创建光盘镜像文件(Linux指令学习笔记)
  9. 将solr3.5整合到Tomcat6.x中
  10. Asp.Net Web API 2(CRUD操作)第二课
  11. NGINX----源码阅读----(option配置脚本)
  12. 为什么说Neutron不是SDN?
  13. Python之路-python介绍
  14. 小白进阶之Scrapy(基于Scrapy-Redis的分布式以及cookies池)
  15. Python基础知识当中容易混淆的几个知识点
  16. 爬虫_腾讯招聘(xpath)
  17. DNS缓存欺骗攻击
  18. STM32 printf函数
  19. redis 安装 ,sea 比较友好的一种
  20. PHP框架 Yii framework 用yiic命令时提示“php.exe”不是内部或外部命令

热门文章

  1. SVN学习笔记
  2. 51 nod 1495 中国好区间 奇葩卡时间题 700ms 卡O(n*log(n)), 思路:O(n)尺取法
  3. 51nod 1536不一样的猜数游戏 思路:O(n)素数筛选法。同Codeforces 576A Vasya and Petya&#39;s Game。
  4. Elevator poj3539
  5. Greatest Common Increasing Subsequence hdu1423
  6. HDU-2222文字检索
  7. 关于离线底图和离线shp文件的加载
  8. 关于http与https区别
  9. python 设计模式,“多”例模式
  10. Activiti 用户任务关联自定义表单