树形dp--hdu 3534 Tree
Tree
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 906 Accepted Submission(s): 268
the edge is len.
1 2 100
2 3 50
2 4 50
4
1 2 100
2 3 50
3 4 50
200 1
题意:给出一颗树(n个顶点,n-1条边)
求最长的路径,以及最长路径的条数。
路径无非就是连接两个点直接的路。
因为是一颗树,所以连接两个点肯定是唯一的路径。
其实就是求两点间距离的最大值,以及这个最大值有多少个。
首先统计出结点到叶子结点的最长距离和次长距离。
然后找寻经过这个点的,在这个为根结点的子树中的最长路径个数目。
...思路参考于kuangbin博客
代码:
#include "stdio.h" //poj 3534 Tree 树形dp
#include "string.h" #define N 100100 struct node
{
int x,y;
int weight;
int next;
}edge[*N];
int idx,head[N]; void Init()
{
idx = ;
memset(head,-,sizeof(head));
} void Add(int x,int y,int weight)
{
edge[idx].x = x;
edge[idx].y = y;
edge[idx].weight = weight;
edge[idx].next = head[x];
head[x] = idx++;
} int maxn[N]; //最长距离
int smaxn[N];//次长距离
int maxn_num[N]; //最长距离数目
int smaxn_num[N]; //次长距离数目
int path[N]; //经过点i的最长距离长度
int num[N]; //经过点i的最长距离数目 void DFS(int x,int father)
{
int i,y;
maxn[x] = smaxn[x] = ;
maxn_num[x] = smaxn_num[x] = ;
for(i=head[x]; i!=-; i=edge[i].next)
{
y = edge[i].y;
if(y==father) continue;
DFS(y,x);
if(maxn[x] < maxn[y]+edge[i].weight)
{
smaxn[x] = maxn[x];
smaxn_num[x] = maxn_num[x];
maxn[x] = maxn[y]+edge[i].weight;
maxn_num[x] = maxn_num[y];
}
else if(maxn[x]==maxn[y]+edge[i].weight)
maxn_num[x] += maxn_num[y];
else if(smaxn[x] < maxn[y]+edge[i].weight)
{
smaxn[x] = maxn[y]+edge[i].weight;
smaxn_num[x] = maxn_num[y];
}
else if(smaxn[x] == maxn[y]+edge[i].weight)
smaxn_num[x] += maxn_num[y];
}
if(maxn_num[x]==) //叶子节点,赋初值
{
maxn[x] = smaxn[x] = ;
maxn_num[x] = smaxn_num[x] = ;
path[x] = ;
num[x] = ;
return ;
}
int c1; //统计以x为根节点的最长距离数目
int c2; //统计以x为根节点的次长距离数目
c1 = c2 = ;
for(i=head[x]; i!=-; i=edge[i].next)
{
y=edge[i].y;
if(y==father) continue;
if(maxn[x] == maxn[y]+edge[i].weight)
c1++;
else if(smaxn[x] == maxn[y]+edge[i].weight)
c2++;
}
path[x] = ;
num[x] = ;
if(c1>=)
{
int tmp = ;
path[x] = maxn[x]*;
for(i=head[x]; i!=-; i=edge[i].next)
{
y = edge[i].y;
if(y==father) continue;
if(maxn[x]==maxn[y]+edge[i].weight)
{
num[x] += tmp*maxn_num[y];
tmp += maxn_num[y];
}
}
}
else if(c1>= && c2>=)
{
path[x] = maxn[x]+smaxn[x];
for(i=head[x]; i!=-; i=edge[i].next)
{
y = edge[i].y;
if(y==father) continue;
if(maxn[x]==maxn[y]+edge[i].weight)
{
num[x] = smaxn_num[x]*maxn_num[y];
}
}
}
else
{
path[x] = maxn[x];
num[x] = maxn_num[x];
}
} int main()
{
int n;
int i,j;
int x,y,k;
while(scanf("%d",&n)!=EOF)
{
Init();
for(i=; i<n; ++i)
{
scanf("%d %d %d",&x,&y,&k);
Add(x,y,k);
Add(y,x,k);
}
DFS(,-);
int dist=,snum=;
for(i=; i<=n; ++i)
{
if(path[i]>dist)
{
dist = path[i];
snum = num[i];
}
else if(path[i]==dist)
{
snum += num[i];
}
}
printf("%d %d\n",dist,snum);
}
return ;
}
树形dp--hdu 3534 Tree的更多相关文章
- fwt优化+树形DP HDU 5909
//fwt优化+树形DP HDU 5909 //见官方题解 // BestCoder Round #88 http://bestcoder.hdu.edu.cn/ #include <bits/ ...
- 【树形dp】Apple Tree
[poj2486]Apple Tree Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10800 Accepted: 3 ...
- HDU 3534 Tree (经典树形dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3534 题意: 给你一棵树,问你有多少对点的距离等于树的直径. 思路: dp[i][0]表示在i的子树中 ...
- HDU - 1054 Strategic Game(二分图最小点覆盖/树形dp)
d.一颗树,选最少的点覆盖所有边 s. 1.可以转成二分图的最小点覆盖来做.不过转换后要把匹配数除以2,这个待细看. 2.也可以用树形dp c.匈牙利算法(邻接表,用vector实现): /* 用ST ...
- 算法笔记--树的直径 && 树形dp && 虚树 && 树分治 && 树上差分 && 树链剖分
树的直径: 利用了树的直径的一个性质:距某个点最远的叶子节点一定是树的某一条直径的端点. 先从任意一顶点a出发,bfs找到离它最远的一个叶子顶点b,然后再从b出发bfs找到离b最远的顶点c,那么b和c ...
- 2017 Multi-University Training Contest - Team 1 1003&&HDU 6035 Colorful Tree【树形dp】
Colorful Tree Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)T ...
- [HDU 5293]Tree chain problem(树形dp+树链剖分)
[HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...
- HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...
- (中等) HDU 5293 Tree chain problem,树链剖分+树形DP。
Problem Description Coco has a tree, whose vertices are conveniently labeled by 1,2,…,n.There are ...
- hdu 5909 Tree Cutting [树形DP fwt]
hdu 5909 Tree Cutting 题意:一颗无根树,每个点有权值,连通子树的权值为异或和,求异或和为[0,m)的方案数 \(f[i][j]\)表示子树i中经过i的连通子树异或和为j的方案数 ...
随机推荐
- TCP和UDP之间的区别
TCP---传输控制协议,提供的是面向连接.可靠的字节流服务.当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据.TCP提供超时重发,丢弃重复数据,检验数据,流量控制等 ...
- 浅谈ImageList
ImageList组件用了很久,但是一直不太清楚它的实现原理,今天专门特意花了时间倒腾了下,终于弄明白了!于是在这里和大家分享下! 在设计页面中打卡工具箱-组件 找到ImageList组件,将它直接拖 ...
- csharp: 用Enterprise Library对象实体绑定数据
Enterprise Library: https://msdn.microsoft.com/en-us/library/ff648951.aspx /// <summary> /// 是 ...
- nginx配合modsecurity实现WAF功能
一.准备工作 系统:centos 7.2 64位.nginx1.10.2, modsecurity2.9.1 owasp3.0 1.nginx:http://nginx.org/download/ng ...
- C语言动态调用库(转)
转自:http://cloverprince.iteye.com/blog/481309 现有一个主程序用C语言写成.现在要允许第三方开发人员编写扩展的模块,约定第三方开发的模块必须提供一系列已知名称 ...
- dubbo序列化的一点注意
最近工作中遇见了一个小问题,在此记录一下,大致是这样的,有一父类,有一个属性traceId,主要是记录日志号,这样可以把所有日志串起来,利于排查问题,所有的pojo对象继承于此,但是其中一同事在子类p ...
- 移位操作<<和>>,是逻辑数字上的移动(和大端小端无关)
问题描述 这几天帮同事调试DSP TMS320F28335,这鬼东西蛋疼死了.char是16bit的,16位就是他的最小内存单元.但是PC机串口发过来的有8bit的数据,然后转换就出问题. 一开始不知 ...
- ALV要特别小心的一些地方
1.在ALV报表里面如果你做了一个字段可编辑而且这个字段是带有小数的数量或者金额,这时候当你输入一个数字保存或者去操作的时候发现他的值会变掉,这个要在设置列属性的时候给他对应的参考表和字段L_FIEL ...
- SharePoint 新特性及安装需知
以下内容转自Kaneboy 大牛,但我在安装正式版的过程中发现一些问题,主要是.net 版本的问题,弄了我一个晚上,我在下面标出来了.我的安装环境是Windows server 2012 R2 关于详 ...
- Hadoop技术内幕(YARN)第4章问题部分答案
问题1:改写DistributedShell程序,使得每个container运行在不同节点上(目前是随机的,可能运行在任意节点上). 问题2:改写DistributedShell程序,使得某个用户指定 ...