题干:

There was a civil war between two factions in Skyrim, a province of the Empire on the continent of Tamriel. The Stormcloaks, led by Ulfric Stormcloak, are made up of Skyrim's native Nord race. Their goal is an independent Skyrim free from Imperial interference. The Imperial Legion, led by General Tullius, is the military of the Empire that opposes the Stormcloaks and seeks to reunite and pacify the province.

The current target of General Tullius is to defend Whiterun City. Near by this city there are NN towers under the Empire's control. There are N−1N−1 roads link these tower, so solders can move from any tower to another one through these roads.

In military affairs, tactical depth means the longest path between two towers of all. Larger the tactical depth is, more stable these towers are.

According to the message sent by spies, General Tullius believe that Stormcloaks is planning to attack one of these roads, and his towers would be divided into two parts. However, Tullius does not know which one, so he supposes the possibility that Stormcloaks attack these roads are the same. Now, General Tullius ask for your help, to calculate the expectation of tactical depth after this attack.

To avoid the issue of precision, you need to calculate expectationoftacticaldepth×(N−1)expectationoftacticaldepth×(N−1).

Input

The first line of input contains an integer tt, the number of test cases. tt test cases follow. 
For each test case, in the first line there is an integer N(N≤100000)N(N≤100000). 
The ii-th line of the next N−1N−1 lines describes the ii-th edge. Three integers u,v,w (0≤w≤1000)u,v,w (0≤w≤1000) describe an edge between uu and vv of length ww.

Output

For each test cases, output expectationoftacticaldepth×(N−1)expectationoftacticaldepth×(N−1).

Sample Input

2
3
2 1 2
3 2 5
5
2 1 7
3 1 7
4 2 5
5 2 6

Sample Output

7
63

题目大意:

给出一棵树,边上有权值,现在毁掉任意一条边,分成两部分,求这两部分中最远的两点距离期望,答案*(n-1)

一句话题意:

N个点的一棵带权树。切掉某条边的价值为切后两树直径中的最大值。求各个边切掉后的价值和(共N-1项)。

解题报告:

说白了就是求最远距离加成和 
对于一棵树来说,两点最远的距离,考虑两点: 
1.最长链没有被拆开,那么答案就是最长链; 
2.最长链被拆开了,那么答案一定在最长链的端点到某个叶子结点上; 
第一点很显然,关于第二点的证明很简单,假设最长路不是最长链的端点到某个叶子结点,那么另一条更长的路径会取代他成为树的直径,与已知矛盾。

有了这个结论,这个题就好做了,首先预处理出最长链,数组存下来,然后对于每个最长链上的结点预处理出它的权值最大的叶子结点(不在最长链上),注意这里的处理看似是n^2的,但是因为是一棵树,所以其实每个点只会被扫到一遍所以是线性的。剩下的就是处理最长链左边和右边的拆开后的最大值了,左右扫一遍,两个数组LR存下来,最后On扫一遍最长链,取LR中最大值得到答案。

刚开始想在bfs的过程中就处理处nxt数组和nxtw数组,后来发现不行,因为你不能保证dis[v]>ans的时候更新的一定是最终选择的路径,所以还是需要从起点到终点dfs一次,在回溯的时候这条路径一定是我们选择的。

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define F first
#define S second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 2e5 + 5;
struct Edge {int u,v;ll w;int ne;
} e[MAX];
int head[MAX],tot,n;//记录边数
int path[MAX],nxt[MAX],top;//top记录最长链上的顶点数
ll dis[MAX],nxtw[MAX],sum[MAX],val[MAX],L[MAX],R[MAX];
int flag[MAX];
void add(int u,int v,ll w) {e[++tot].u = u;e[tot].v = v;e[tot].w = w;e[tot].ne = head[u];head[u] = tot;
}
int bfs(int st,ll& ans) {queue<int> q;int retp = st;ans = 0;//注意初始化 for(int i = 1; i<=n; i++) dis[i] = -1,nxt[i]=-1;q.push(st);dis[st] = 0; while(!q.empty()) {int cur = q.front();q.pop();for(int i = head[cur]; ~i; i = e[i].ne) {int v = e[i].v;if(dis[v] != -1) continue;q.push(v);dis[v] = dis[cur] + e[i].w;if(dis[v] >= ans) {ans = dis[v];retp = v;}}}return retp;
}
int st,ed;
bool ok;
void dfs(int cur,int fa) {if(cur == ed) {ok = 1;return;}for(int i = head[cur]; ~i; i = e[i].ne) {int v = e[i].v;if(v == fa) continue;dfs(v,cur);if(ok == 1) {nxt[cur] = v;nxtw[cur] = e[i].w;return;}}
}
ll dfs2(int cur,int fa) {ll res = 0;for(int i = head[cur]; ~i; i = e[i].ne) {int v = e[i].v;if(flag[v] == 1 || v == fa) continue;res = max(res,dfs2(v,cur) + e[i].w);}return res;
}
int main()
{int t;cin>>t;while(t--) {scanf("%d",&n);//inittot=top=0;ok=0;for(int i = 1; i<=n; i++) head[i] = -1,sum[i] = 0,val[i]=L[i]=R[i]=0,flag[i] = 0;for(int a,b,i = 1; i<=n-1; i++) {ll c;scanf("%d%d%lld",&a,&b,&c);add(a,b,c);add(b,a,c);}ll maxx,ans=0;st = bfs(1,maxx); ed = bfs(st,maxx);dfs(st,-1);for(int i = st; i!=-1; i = nxt[i]) {flag[i] = 1;path[++top] = i;}ans = maxx * (n-top);for(int i = 1; i<top; i++) {//枚举他和他儿子的那条边 sum[i+1] = sum[i] + nxtw[path[i]];//照这么来看的话还是递归的写法会好一些,因为正好就是儿子节点代表儿子到父亲的那条边 }for(int i = 1; i<=top; i++) {//搜索中间点 (st和ed也可以搜,只不过搜出来结果肯定是0)val[i] = dfs2(path[i],-1);}for(int i = 1; i<=top; i++) {//枚举割最长链上的每一条边 L[i] = max(val[i] + sum[i],L[i-1]);}for(int i = top; i>=1; i--) {R[i] = max(R[i+1],val[i] + (sum[top]-sum[i]));}for(int i = 1; i<top; i++) {ans += max(L[i],R[i+1]);}printf("%lld\n",ans);}return 0 ;
}

【HDU - 5886】Tower Defence(树的直径,思维,dp)相关推荐

  1. hdu 5886 Tower Defence 树形期望dp 雪漫防守战

    题意: 风暴斗篷现在要攻打雪漫城.雪漫城有n(n≤100000)个哨塔防守,哨塔之间有n-1条路相连,(构成一棵树).现在预测到风暴斗篷要进攻某一条路,然后这棵树就一分为二,现在要得到分开后的最长路. ...

  2. 动态规划(树形DP):HDU 5886 Tower Defence

    Sample Input 2 3 2 1 2 3 2 5 5 2 1 7 3 1 7 4 2 5 5 2 6 Sample Output 7 63 这类题目就是分类讨论,需要多做做. 1 #inclu ...

  3. HDU - 4607 Park Visit (树的直径)

    http://acm.hdu.edu.cn/showproblem.php?pid=4607 题意 一颗n个顶点的树,现在只想访问其中k个,问最短路径长度为多少. 分析 首先,最短的路径当然是一条链. ...

  4. HDU 4607 Park Visit(树的直径)

    题目大意:给定一棵树,让求出依次访问k个点的最小花费,每条边的权值都为1. 思路:如果能一直往下走不回来,那么这个路径肯定是最小的,这就取决于给定的k,但是怎么确定这个能一直走的长度呢,其实这个就是树 ...

  5. POJ 1849 Two(树的直径+思维)

    题目链接:http://poj.org/problem?id=1849        题意是有n个点,n-1条边(树形图),在s点放两个机器人,问这两个机器人遍历完所有的点的最少花费(不用回到原点). ...

  6. Book of Evil(树的直径+思维)

    Book of Evil Paladin Manao caught the trail of the ancient Book of Evil in a swampy area. This area ...

  7. HDU5886 Tower Defence 【两遍树形dp】【最长链预处理】

    题意:N个点的一棵带权树.切掉某条边的价值为切后两树直径中的最大值.求各个边切掉后的价值和(共N-1项). 解法一: 强行两遍dp,思路繁琐,维护东西较多: dis表示以i为根的子树的直径,dis2表 ...

  8. [树的直径 树形DP] UOJ #11【UTR #1】ydc的大树

    题解链接 大意是我们求出直径的中心 那么到最远点必然经过中心 把它提到根 就可以在枚举删的白点时很快统计出能够使多少个黑点不高兴 #include<cstdio> #include< ...

  9. 模板 - 树上问题(树的直径、动态查询树的直径、树的重心)

    整理的算法模板合集: ACM模板 目录 一.树的直径 树形DP 两次DFS / BFS(找到直径的两个端点) 二.动态修改树的边权并求每个时刻的直径(线段树) 三.树的重心 一.树的直径 树的直径满足 ...

最新文章

  1. LSTM 时间序列数据的异常检测
  2. Node_exporter+Prometheus+Grafana 快速实现Linux系统性能数据提取、存储和可视化展示
  3. 71.数据模型有哪几种?特征?
  4. 2.1.2 Dropout正则化以及其他正则化
  5. 构建高性能J2EE应用的十个技巧
  6. 材料科学中的数据挖掘:晶体图神经网络解读与代码解析
  7. 王者体验服服务器注册人数已满,王者荣耀体验服注册人数达到上限怎么回事?体验服测试最新申请方法...
  8. mysql 左连接 重复_mysql左连接重复行
  9. activeMQ发送与接受消息模板代码
  10. jenkins支持PHP,jenkins发布php代码
  11. easyui table 如何只展示一条_如何使用MySQL,这些操作你得明白!
  12. Javascript的原型链
  13. 机器人防火墙出击 提升在线业务的安全未来
  14. 网闸端口限制时,用HaneWin NFS Server来部署单一接口来交互,实现挂载便于访问
  15. 经典laravel后台管理系统
  16. 一文读懂锂电池叠片、卷绕工艺区别!
  17. 专家有料 | 李中文:美团软件成分安全分析(SCA)能力的建设与演进
  18. 前端:LayUi监听表格单元格,编辑后恢复原数据
  19. esxi显卡给2个虚拟机_利用ESXi实现一拖二和各系统独立运行——基础篇
  20. Java 求100以内的质数

热门文章

  1. Silverlight反编译系列二常见代码(自动生成属性CompilerGenerated,代码)
  2. [hackinglab][CTF][基础关][2020] hackinglab 基础关 writeup
  3. [Leedcode][JAVA][第542题][01矩阵][BFS]
  4. ps aux grep java_linux命令ps-aux监控java进程
  5. 适合文科女孩子学的计算机类专业,文科女生最吃香的专业2021 哪些专业有前景...
  6. java处理中文字符串_Java实现读取文章中重复出现的中文字符串
  7. html简单父子页面,js 的 iframe 父子页面通信的简单方法
  8. 关闭SQLite3中的journal暂存档
  9. Android串口通信实例分析【附源码】
  10. 【转】DICOM的常用Tag分类和说明!!!!