树形DP(统计直径的条数 HDU3534)
分析:首先树形dp(dfs计算出每个点为根节点的子树的最长距离和次长距离),然后找出L=dis[u][0]+dis[u][1]最长的那个点u,然后在以u为根节点dfs,统计长度为L的条数:具体做法:把u的儿子节点为根节点的子树深搜遍历到每个叶子节点,用h[dist[v]]统计该子树中u到v的距离,然后对于遍历过的叶子节点且不再当前子树中的s[L-dist[v]]的个数加到ans中,最后ans即为所求条数:
- #pragma comment(linker, "/STACK:1024000000,1024000000")
- #include"stdio.h"
- #include"string.h"
- #include"stdlib.h"
- #include"queue"
- #include"algorithm"
- #include"string.h"
- #include"string"
- #include"math.h"
- #include"vector"
- #include"stack"
- #include"map"
- #define eps 1e-4
- #define inf 0x3f3f3f3f
- #define M 100009
- #define PI acos(-1.0)
- using namespace std;
- struct node
- {
- int u,v,next;
- __int64 w;
- }edge[M*2];
- int t,head[M],belong[M],dis[M][4],degree[M];
- int cnt;
- __int64 dist[M],a[M],L,ans;
- map<__int64,int>s,h;
- void init()
- {
- t=0;
- memset(head,-1,sizeof(head));
- }
- void add(int u,int v,int w)
- {
- edge[t].u=u;
- edge[t].v=v;
- edge[t].w=w;
- edge[t].next=head[u];
- head[u]=t++;
- }
- void dfs(int u,int f)
- {
- dis[u][0]=0;
- dis[u][1]=0;
- for(int i=head[u];~i;i=edge[i].next)
- {
- int v=edge[i].v;
- if(v==f)continue;
- dfs(v,u);
- if(dis[u][0]<dis[v][0]+edge[i].w)
- {
- dis[u][1]=dis[u][0];
- dis[u][0]=dis[v][0]+edge[i].w;
- }
- else if(dis[u][1]<dis[v][0]+edge[i].w)
- dis[u][1]=dis[v][0]+edge[i].w;
- }
- }
- void dfs2(int u,int f);
- void dfs1(int u,int f)
- {
- s.clear();
- for(int i=head[u];~i;i=edge[i].next)
- {
- int v=edge[i].v;
- if(v==f)continue;
- h.clear();
- dist[v]=edge[i].w;
- cnt=0;
- dfs2(v,u);
- for(int j=0;j<cnt;j++)
- {
- s[a[j]]+=h[a[j]];
- }
- }
- }
- void dfs2(int u,int f)
- {
- if(degree[u]==1)
- {
- if(h[dist[u]]==0)
- a[cnt++]=dist[u];
- h[dist[u]]++;
- if(s[L-dist[u]])
- {
- ans+=s[L-dist[u]];
- //printf("%d %d\n",s[L-dist[u]],h[dist[u]]);
- }
- }
- for(int i=head[u];i!=-1;i=edge[i].next)
- {
- int v=edge[i].v;
- if(v==f)continue;
- dist[v]=dist[u]+edge[i].w;
- dfs2(v,u);
- }
- }
- int main()
- {
- int n,i,a,b;
- __int64 c;
- while(scanf("%d",&n)!=-1)
- {
- init();
- memset(degree,0,sizeof(degree));
- for(i=1;i<n;i++)
- {
- scanf("%d%d%I64d",&a,&b,&c);
- add(a,b,c);
- add(b,a,c);
- degree[a]++;
- degree[b]++;
- }
- if(n==1)
- {
- printf("0 1\n");
- continue;
- }
- if(n==2)
- {
- printf("%I64d 1\n",edge[0].w);
- continue;
- }
- for(i=1;i<=n;i++)
- {
- if(degree[i]>1)
- {
- dfs(i,-1);
- break;
- }
- }
- int id=1;
- L=dis[id][0]+dis[id][1];
- for(i=2;i<=n;i++)
- {
- if(dis[id][0]+dis[id][1]<dis[i][0]+dis[i][1])
- {
- L=dis[i][0]+dis[i][1];
- id=i;
- }
- }
- ans=0;
- dfs1(id,-1);
- printf("%I64d %I64d\n",L,ans);
- }
- }
树形DP(统计直径的条数 HDU3534)的更多相关文章
- hdoj3534(树形dp,求树的直径的条数)
题目链接:https://vjudge.net/problem/HDU-3534 题意:给出一棵树,求树上最长距离(直径),以及这样的距离的条数. 思路:如果只求直径,用两次dfs即可.但是现在要求最 ...
- 树形DP 统计树中长度为K的路径数量——Distance in Tree
一.问题描述 给出一棵n个节点的树,统计树中长度为k的路径的条数(1<=n<=50000 , 1<=k<=500). 二.解题思路 设d[i][k]表示以i为根节点长度为k的路 ...
- bzoj1912 树形dp求直径(新写法),求直径的两端点
通过回溯法可以求出直径的两个端点,同时注意有负权边的树求直径不可以用两次dfs来求,而必须用dp做 /* 分情况讨论问题 一条边也不加的情况,显然每条边要扫描两次, 该情况的答案是2(n-1) 只加一 ...
- tarjan算法求缩点+树形DP求直径
hdu4612 Warm up Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) ...
- mysql根据分组和条件查询以后如何统计记录的条数
1.子查询,查询出的数据随便起一个别名,然后根据分组和条件查询出的数据,作为一个具有一列的一个表,然后外面的查询查询这个数据表的这一列的总数,即可. SELECT COUNT( * ) FROM ( ...
- Luogu4630 APIO2018 Duathlon 圆方树、树形DP
传送门 要求的是一条按顺序经过\(s,t,c\)三个点的简单路径.简单路径的计数问题不难想到点双联通分量,进而使用圆方树进行求解. 首先将原图缩点,对于一个大小为\(size\)的点双联通分量内,在这 ...
- 洛谷 P2986 [USACO10MAR]Great Cow Gat…(树形dp+容斥原理)
P2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gat… 题目描述 Bessie is planning the annual Great Cow Gathering for c ...
- Codeforces 919D Substring (拓扑排序+树形dp)
题目:Substring 题意:给你一个有向图, 一共有n个节点 , m条变, 一条路上的价值为这个路上出现过的某个字符最多出现次数, 现求这个最大价值, 如果价值可以无限大就输出-1. 题解:当这个 ...
- HDU2242 考研路茫茫——空调教室 (双联通分+树形DP)
考研路茫茫——空调教室 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
随机推荐
- wdate-year-month-week-gategory-amount-coin
---2016-12-02 19:46:39 the whole table DISTINCT field SUM(field) COUNT(field) --- 888983 rows OK SEL ...
- 【转】最简单的CI框架入门示例--数据库取数据
1.下载CI框架(自己找) 2.配置 database.php配置: 为数据库服务器设置 connection 参数: $db['default']['hostname'] = "yo ...
- osgi 命令
安装命令 install reference:file:D:/workspace/workspace-osgi/MsgBoxCreateModule 根据 返回的 ID再运行start
- SQL2005的cte递归查询子树
;with cteas(select id,caption,parentid,1 Gen from skywfflow where parentid =0UNION ALL select a.id,a ...
- SQL Server加密存储过程的破解
建好sp后,在“连接到数据库引擎”对话框的“服务器名称”框中,键入 ADMIN:,并在其后继续键入服务器实例的名称.例如,若要连接到名为 ACCT\PAYABLE 的服务器实例,请键入 ADMIN:A ...
- Android Studio工具修理集
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 1.Common依赖项目找不到.因为主项目没有引进setting.gradle 2.从Eclipse ...
- php--group by
1. GROUP BY 是分组查询, 一般 GROUP BY 是和聚合函数配合使用 group by 有一个原则,就是 select 后面的所有列中,没有使用聚合函数的列,必须出现在 group by ...
- ArcGIS API for JavaScript 4.0(一)
原文:ArcGIS API for JavaScript 4.0(一) 最近ArcGIS推出了ArcGIS API for JavaScript 4.0,支持无插件3D显示,而且比较Unity和Sky ...
- -tableView: cellForRowAtIndexPath:方法不执行问题
今天在学习UItableView 的时候,定义了一个属性 @property (weak, nonatomic) NSMutableArray *dataList: 在ViewDidLoad方法方法中 ...
- js操作table倒叙显示序号的问题
今天遇到一奇葩问题,就是在js添加table时,序号是倒叙显示的,而且数据库查出来时正序的,为什么显示是倒叙的呢? 我百度一番,终于有了结果: var newRow=table.insertRow(- ...