Wannafly #1 Treepath(树形DP)
来源:互联网 发布:苏州软件测试工资待遇 编辑:程序博客网 时间:2024/04/28 05:50
problem
给定一棵n个点的树,问其中有多少条长度为偶数的路径。路径的长度为经过的边的条数。x到y与y到x被视为同一条路径。路径的起点与终点不能相同。
Input
第一行一个数n表示点的个数;
接下来n-1行,每行两个整数x,y表示边;
保证输入数据形成一棵树;
1<=n<=100000
Output
一行一个整数表示答案。
Sample Input
3
1 2
1 3
Sample Output
1
思路
考虑tree DP,dp1【】数组表示以当前结点为根的子树中所有到根的路径长度为奇数的结点数
dp2【】数组表示以当前结点为根的子树中所有到根的路径长度为偶数的结点数。就有“父奇为儿偶,父偶为儿奇”
进入每个结点时,初始化为dp1[rt]=0,dp2[rt]=1;
就是说,“零距离”记为1个,这样在计数时,比如叶子节点的父节点,奇数就加上偶数(0+1=1),偶数就加上奇数(0+0=0),符合。
另外,最关键的一点在于 ans+=dp1[rt]*dp2[tt]+dp2[rt]*dp1[tt];
就是说,对当前这个根节点,有一个它的子树到他的奇∗ 另外一个子树的奇(奇+奇=偶)(或者说是已经合并的,实际上这就是一个合并信息到根的过程),和偶∗ 偶(偶+偶=偶),就是ans要加的值。
核心代码为
void dfs(int rt,int f){ dp1[rt]=0; dp2[rt]=1; for(int i=head[rt];i!=-1;i=edges[i].to){ int tt=edges[i].from; if(tt==f) continue; dfs(tt,rt); ans+=dp1[rt]*dp2[tt]+dp2[rt]*dp1[tt]; dp1[rt]+=dp2[tt];//父奇为儿偶 dp2[rt]+=dp1[tt];//父偶为儿奇 }}
代码示例
#include<iostream>#include<string.h>#include<cstdio>using namespace std;const int maxn=100010;int head[maxn<<1];int tot,n;//tot辅助存边(边集数组转邻接表),n为结点数struct Edge{ int from,to;}edges[maxn<<1];void init(){ memset(head,-1,sizeof(head)); tot=0;}void add_edge(int u,int v){ edges[tot].from=v; edges[tot].to=head[u]; head[u]=tot++;}int dp1[maxn],dp2[maxn];//1为奇路径方案数,2为偶路径方案数long long ans=0;//答案void dfs(int rt,int f){ dp1[rt]=0; dp2[rt]=1; for(int i=head[rt];i!=-1;i=edges[i].to){ int tt=edges[i].from; if(tt==f) continue; dfs(tt,rt); ans+=dp1[rt]*dp2[tt]+dp2[rt]*dp1[tt]; dp1[rt]+=dp2[tt]; dp2[rt]+=dp1[tt]; }}int main(){ //ios::sync_with_stdio(false); int u,v; scanf("%d",&n); init(); for(int i=1;i<n;++i){ scanf("%d %d",&u,&v); add_edge(u,v); add_edge(v,u); } dfs(1,-1); cout<<ans<<endl; return 0;}
阅读全文
1 0
- Wannafly #1 Treepath(树形DP)
- Wannafly挑战赛1 Treepath(树形DP,思维)
- 【Wannafly挑战赛1】A Treepath 【树形DP】or 【黑白染色 找规律】
- Wannafly挑战赛1 Treepath
- wannafly 1 treepath
- Wannafly挑战赛1 A.Treepath
- Wannafly挑战赛1 A Treepath
- 牛客网 Treepath 树形dp || 思维
- Wannafly挑战赛1 A.Treepath(dfs)
- Wannafly挑战赛1 A Treepath LCA
- Wannafly挑战赛1A-(树形DP)
- Wannafly挑战赛1:A-Treepath(DFS或BFS)
- nowcoder Wannafly挑战赛1 A 题 【树形dp or 点分治】
- Wannafly挑战赛1 A-DP
- treePath
- Wannafly挑战赛1 C MMSet2 虚树DP
- NOWCODER Treepath (树dp水题)
- Wannafly挑战赛A(概率DP)
- js-无缝滚动-双图切换
- 1013 面向切面编程AOP
- LightOJ
- TLS加密套件
- $array[]=6与$array=6的区别
- Wannafly #1 Treepath(树形DP)
- 从kafka到flink到hbase的心酸路程示例(希望有用)
- 关于sync_with_stdio(false);
- gulp——自动化管理工具
- 从jsp传递一个list到springmvc的Controller
- Python_3
- Qt 打印预览以及打印功能的实现
- Crash的收集
- plsql导入.dmp步骤