树形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的方案数 ...
随机推荐
- 控制器中的Action方法,接收浏览器传过来的参数,总共有几种?
1.根据配置文件中的URL规则 public ActionResult Delete(int id) //id参数就是根据路由里面的参数id来传过来的,这个action方法中的参数一定要和路由中的id ...
- 后缀数组 --- HDU 3518 Boring counting
Boring counting Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=3518 Mean: 给你一个字符串,求:至少出 ...
- [CLR via C#]16. 数组
数组是允许将多个数据项当作一个集合来处理的机制.CLR支持一维数组.多维数组和交错数据(即由数组构成的数组).所有数组类型都隐式地从System.Array抽象类派生,后者又派生自System.Obj ...
- 单例(C#版)
单例: 一个类只有一个实例.巧妙利用了编程语言的一些语法规则:构造函数private, 然后提供一个public的方法返回类的一个实例:又方法和返回的类的实例都是static类型,所以只能被类所拥有, ...
- PDT已有很大改进
受够了NB的低性能文件扫描,也许是时候放弃Netbeans迎接PDT了.
- treap树---营业额统计
台州学院 2924 描述 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况.Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额 ...
- 四、MyBatis主配置文件
//备注:该博客引自:http://limingnihao.iteye.com/blog/1060764 在定义sqlSessionFactory时需要指定MyBatis主配置文件: Xml代码 收藏 ...
- mysql root强密码的必要性max_allowed_packet被改成1024引起的风险
前两天运维反馈说,有些机器的max_allowed_packet隔两天就会被改成1024,导致客户端调用时出错,网上有说内存不够的,也有人工修改的. 运维小姑娘一口咬定肯定没有改过的,而且my.cnf ...
- android:ellipsize实现跑马灯效果总结(转)
最近无意间看到了涉及到跑马灯效果的代码,于是在网上查阅了很多资料,在这里对自己看的一些文章进行一下总结,顺便加上自己的一些体会. 让我们一步步逐渐向下. 首先我们要实现走马灯这样一个效果,通常来说 ...
- ubuntu定时执行脚本(crond)
如果发现您的系统里没有这个命令,请安装下面两个软件包. vixie-cron crontabs crontab 是用来让使用者在固定时间或固定间隔执行程序之用,换句话说,也就是类似使用者的时程表.-u ...