Hdu 4705 Y -- 树形
2013-09-30 10:35
393 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4705
题意:给一棵树,让你找到一个三个节点的集合,这三个节点不能在一条简单的路上(要有支路,或者说有交点,语文表达不好。。。)求一共有几种可能。
思路:用全部可能值 C( N , 3 ) 减去每一条路上的三元集合数ans。
具体做法是:
1>从一个结点a出发,找它所有的子节点的儿子总数had,在每一个子节点的儿子数son。每找到一个子节点,had加上新找到的son数,一条路上可找到的三元集合数就多了(n-had-1)*son个。表示此子节点xi,子节点的儿子xxi和xi的其他未找到的儿子中任选一个xii 组成的三元集合。
2>递归求解。
题意:给一棵树,让你找到一个三个节点的集合,这三个节点不能在一条简单的路上(要有支路,或者说有交点,语文表达不好。。。)求一共有几种可能。
思路:用全部可能值 C( N , 3 ) 减去每一条路上的三元集合数ans。
具体做法是:
1>从一个结点a出发,找它所有的子节点的儿子总数had,在每一个子节点的儿子数son。每找到一个子节点,had加上新找到的son数,一条路上可找到的三元集合数就多了(n-had-1)*son个。表示此子节点xi,子节点的儿子xxi和xi的其他未找到的儿子中任选一个xii 组成的三元集合。
2>递归求解。
#pragma comment(linker, "/STACK:16777216") #include<cstdio> #include<vector> #include<string.h> #include<iostream> using namespace std; #define ll __int64 #define N 100000+5 bool vis ; vector<int>r ; ll n,ans,all; ll dfs(int u) { int v; ll had = 0,son; vis[u]=1; for(unsigned int i = 0;i < r[u].size();i++) { v=r[u][i]; if(!vis[v]) { son = dfs(v); had += son; ans += (n-had-1)*son; //n-已经算过的儿子的数目-u本身==u的其他未算过的儿子数, //再乘上son,当下结点一枝的儿子数 } } return had+1; } void init() { memset(vis,0,sizeof(vis)); for (int i = 0; i < N; i++) { r[i].clear(); } ans = 0; all = n*(n-1)*(n-2)/6;//C(n,3) } int main() { int u,v; while(cin>>n){ init(); for(int i = 1;i<n;i++) { cin>>u>>v; r[u].push_back(v); r[v].push_back(u); } dfs(1); cout<<all-ans<<endl; } return 0; }
相关文章推荐
- 纯jsp打造无限层次的树代码
- ExtJS 4 树
- 数据库表TreeView树的快速生成
- Android树状列表实现
- 数据结构基础攻略——树(Tree)
- iOS 解析xml之——将XML转化为树demo
- 二叉搜索树转换为双向链表 binary search tree to double-linked list
- 面试只Trie树特点和应用场景
- POJ2418-Hardwood Species
- 树的定义definition
- Forest
- 数据结构学习之_二叉树的遍历
- 11.求二叉树中节点的最大距离
- 9.判断整数序列是不是二元查找树的后序遍历结果
- Same Tree
- Symmetric Tree
- Maximum Depth of Binary Tree
- Path Sum
- path sumII
- Sum Root to Leaf Numbers