题意

给定一棵树,计算数集{A,B,C}的个数,其中A,B,C是树上的节点,且不存在一条路径覆盖A,B,C。

思路

朴素的想法是枚举“Y”的中点,然后枚举三条树枝i,j,k,答案就是sigma(Si*Sj*Sk) = [( sigma(Si) )^3 - 3*sigma(Si)*sigma(Si^2) + 2*sigma(Si^3)] / 6,其中Si表示i子树上节点个数。但是这样太麻烦了。 我们考虑用补集来做。计算A,B,C被一条路径覆盖的个数。那么这样假设A<B<C,我们就可以枚举B,然后枚举两个树枝i,j,答案就是sigma(Si*Sj) =[ ( sigma(Si) )^2 - sigma ( Si^2 ) ] / 2,时间复杂度O(n)。

代码

[cpp] #include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <string> #include <cstring> #include <vector> #include <set> #include <stack> #include <queue> #define MID(x,y) ((x+y)/2) #define MEM(a,b) memset(a,b,sizeof(a)) #define REP(i, begin, end) for (int i = begin; i <= end; i ++) #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; typedef long long LL; typedef vector <int> VI; const int MAXV = 100005; int n; VI adj[MAXV]; LL res, num[MAXV]; bool vis[MAXV]; void dfs(int u){ vis[u] = true; int son = 0; num[u] = 1; VI tmpadj; for (int i = 0; i < (int)adj[u].size(); ++ i){ int v = adj[u][i]; if (!vis[v]){ tmpadj.push_back(v); son ++; dfs(v); num[u] += num[v]; } } if (son > 0){ if (u == 1 && son == 1) return ; LL uans = (LL)(n-1)*(n-1); for (int i = 0; i < (int)tmpadj.size(); ++ i){ int v = tmpadj[i]; uans -= (LL)num[v] * num[v]; } uans -= (LL)(n-num[u])*(n-num[u]); uans /= 2; res += uans; } return ; } int main(){ while(scanf("%d", &n) != EOF){ REP(i, 0, n) adj[i].clear(); REP(i, 1, n-1){ int u, v; scanf("%d %d", &u, &v); adj[u].push_back(v); adj[v].push_back(u); } res = 0; MEM(num, 0); MEM(vis, false); dfs(1); printf("%I64d\n", (LL)n*(n-1)*(n-2)/6 - res); } return 0; } [/cpp]

转载于:https://www.cnblogs.com/AbandonZHANG/p/4114111.html

HDU 4705 Y (树形DP)相关推荐

  1. HDU - 4705 Y(树形dp)

    题目链接:点击查看 题目大意:给出一棵树,求三个点不在一条线上的个数 题目分析:正难取反,正着求不管是暴力还是有点技巧都是实现不了的,我们可以求出来三个点在一条直线上的方案数,然后用总的排列组合的方案 ...

  2. HDU 5148 Cities (树形DP)*

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5148 #include<bits/stdc++.h> using namespace st ...

  3. HDU 2196 Computer 树形DP经典题

    链接:http://acm.hdu.edu.cn/showproblem.php? pid=2196 题意:每一个电脑都用线连接到了还有一台电脑,连接用的线有一定的长度,最后把全部电脑连成了一棵树,问 ...

  4. HDU 4616 Game 树形DP

    Problem Description Nowadays, there are more and more challenge game on TV such as 'Girls, Rush Ahea ...

  5. HDU 5148 Cities 树形DP(背包)

    HDU 5148 题意;n个点的树,第i条边长度为c[i],任意选中k个点为特殊点,这k个点中,任意两点间距离的期望值最小为多少? n<=2000,k<=min(50,n) c[i]< ...

  6. HDU Starship Troopers (树形DP)

    Starship Troopers Time Limit : 10000/5000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) ...

  7. hdu 2196(经典树形dp)

    题意:给你一颗边带权值的树,求树上的每一点距离其最远的一个点的距离 解题思路:这道题网上说是经典的树形dp,不过确实很巧妙.两次dfs应该是比较好想到的,因为某节点最大的距离要么就是一直走到叶子节点, ...

  8. HDU - 5242 Game(树形dp+树链剖分/树上贪心+思维)

    题目链接:点击查看 题目大意:给出一棵包含n个节点的树,每个节点都有一个权值,整棵树的根是点1,问从点1开始向下一直走到叶子节点,可以走k次,怎么样走权值和最大,每个节点被走过一次后权值会变为0 题目 ...

  9. HDU - 2196 Computer(树形dp)

    题目链接:点击查看 题目大意:给定n个点以及n-1条边,保证可以组成一棵树,问每个点所能到达的最远距离 题目分析:首先这是一颗无向图所组成的树,经过分析,我们可以得到任何一个点,对于它所能到达的最远距 ...

最新文章

  1. 张仰彪第二排序法_十大排序之冒泡和选择排序
  2. [转]Android NDK几点回调方式
  3. python依照概率抽样_R语言之随机数与抽样模拟篇
  4. CTC 解码算法之 prefix beam search
  5. 各种当下编程风格一览,看一看你属于哪一种?
  6. 查看Oracle当前用户下的信息
  7. HDU2039 三角形【水题】
  8. flask html 得到文本框 input的内容_你需要知道的HTML知识
  9. python实现word文档合并
  10. 流畅安装、简单使用annie下载B站视频
  11. Word技巧:如何使用正则表达式高效替换
  12. vue面试题目(更新版)
  13. 华为数通笔记-IPV6基础
  14. 【bzoj3698】XWW的难题 有源汇上下界网络流最大流
  15. NLP词向量和句向量方法总结及实现
  16. 回忆高中数学--概述“奇变偶不变,符号看象限”
  17. javascript常用语句,如表单禁止复制,剪切等
  18. 什么是通达信接口函数
  19. 《嵌入式Linux软硬件开发详解——基于S5PV210处理器》——2.5 WM8960音频编解码芯片...
  20. MFC串口调试工具教程

热门文章

  1. Python Django安装MySQL库
  2. MySQL列转行sql语句
  3. sqserver对比oracle的区别,oracle和sqlserver比较
  4. protect 继承_C++ protected继承和private继承是不是没用的废物?
  5. cordova 更改app版本_ionic项目中使用cordova-hot-code-push插件
  6. python简单爬虫手机号_python手机号前7位归属地爬虫代码实例
  7. python爬虫科研数据提取_python爬虫数据提取四之pyquery
  8. 反问疑问_句子练习大全(反问、疑问、设问、病句等练习)
  9. java判断括号是否闭合_【python每日一练】有效括号
  10. 乐鑫代理启明云端分享|ESP32驱动1.54inch(240*240)彩屏