Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 242    Accepted Submission(s): 80


Problem Description
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 N towers
under the Empire's control. There are N−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).
 

Input
The first line of input contains an integer t,
the number of test cases. t test
cases follow.

For each test case, in the first line there is an integer N(N≤100000).

The i-th
line of the next N−1 lines
describes the i-th
edge. Three integers u,v,w (0≤w≤1000) describe
an edge between u and v of
length w.
 

Output
For each test cases, output 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

题意:给你一棵树,树的每条边都有权值,每次等概率地切掉一条边,求所有切掉一条边后情况的直径和。

思路:和network那题一样,是树形dp,这题主要是分类讨论,有5种情况。假设现在访问的点是x,连接x的边对应的子节点是y,那么切去x-y这条边后,两部分的较大直径只可能是:1.以y为根的子树的直径。2.a,b节点是x的子节点,且lca(a,b)是x,找到满足前面条件的最长a-x-b路径。3.a是x的子节点,满足前面条件的最大的以a为根的子树。4.设x的父亲是h,从父亲节点h转移过来的树的直径(这里的直径不包括x这棵子树)5.从父亲节点过来,经过x,并且到达x子树下的最远点,这条路径的距离。

这里要开6个数组,分别是dp[x](以x为根的子树的直径),dist1[x],dist1id[x],dist2[x],dist2id[x],dist3[x],dist3id[x](x节点到其子节点的第一大,第二大,第三大距离及对应的x孩子节点的编号),dpzishu1id[x],dpzishu2id[x](表示x的子树中,不包括x节点,直径最大和次大的直径和孩子节点的编号)。

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<string>
#include<bitset>
#include<algorithm>
using namespace std;
#define lson th<<1
#define rson th<<1|1
typedef long long ll;
typedef long double ldb;
#define inf 99999999
#define pi acos(-1.0)
#define Key_value ch[ch[root][1]][0]
#define maxn 100050
ll dp[maxn],dpzishu1[maxn],dpzishu2[maxn],dist1[maxn],dist2[maxn],dist3[maxn];
ll dpid[maxn],dpzishu1id[maxn],dpzishu2id[maxn],dist1id[maxn],dist2id[maxn],dist3id[maxn];
int first[maxn],tot;
ll ans;
struct edge{
int to,next;
ll len;
}e[2*maxn];
void addedge(int u,int v,ll len)
{
e[tot].to=v;e[tot].len=len;e[tot].next=first[u];
first[u]=tot++;
} void update(int u,int v,ll len)
{
int i,j;
if(dist1[v]+len>=dist1[u]){
dist3[u]=dist2[u];dist3id[u]=dist2id[u];
dist2[u]=dist1[u];dist2id[u]=dist1id[u];
dist1[u]=dist1[v]+len;dist1id[u]=v;
}
else if(dist1[v]+len>=dist2[u]){
dist3[u]=dist2[u];dist3id[u]=dist2id[u];
dist2[u]=dist1[v]+len;dist2id[u]=v;
}
else if(dist1[v]+len>=dist3[u]){
dist3[u]=dist1[v]+len;dist3id[u]=v;
}
}
void update1(int u,int v)
{
int i,j;
if(dp[v]>dpzishu1[u]){
dpzishu2[u]=dpzishu1[u];dpzishu2id[u]=dpzishu1id[u];
dpzishu1[u]=dp[v];dpzishu1id[u]=v;
}
else{
dpzishu2[u]=dp[v];dpzishu2id[u]=v;
}
}
void dfs1(int u,int pre)
{
int v,i,j;
dp[u]=dist1[u]=dist2[u]=dist3[u]=dpzishu1[u]=dpzishu2[u]=0;
dpid[u]=dist1id[u]=dist2id[u]=dist3id[u]=dpzishu1id[u]=dpzishu2id[u]=-1;
for(i=first[u];i!=-1;i=e[i].next){
v=e[i].to;
if(v==pre)continue;
dfs1(v,u);
update(u,v,e[i].len);
update1(u,v);
}
dp[u]=max(dpzishu1[u],dist1[u]+dist2[u]);
} void dfs2(int u,int pre,ll juli,ll zhijing)
{
int v,i,j;
ll zj,juli1;
for(i=first[u];i!=-1;i=e[i].next){
v=e[i].to;
if(v==pre)continue;
zj=0;
///2
if(dist1id[u]==v){
zj=dist2[u]+dist3[u];
}
else if(dist2id[u]==v){
zj=dist1[u]+dist3[u];
}
else{
zj=dist1[u]+dist2[u];
}
///3
if(dpzishu1id[u]==v){
zj=max(zj,dpzishu2[u]);
}
else{
zj=max(zj,dpzishu1[u]);
}
///4
zj=max(zj,zhijing);
///5
if(dist1id[u]==v){
zj=max(zj,dist2[u]+juli);
}
else{
zj=max(zj,dist1[u]+juli);
}
ans+=max(zj,dp[v]);
if(dist1id[u]==v)juli1=max(juli,dist2[u]);
else juli1=max(juli,dist1[u]);
dfs2(v,u,juli1+e[i].len,zj);
}
} int main()
{
int n,m,i,j,T,c,d;
ll f;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n); tot=0;
for(i=1;i<=n;i++)first[i]=-1; for(i=1;i<=n-1;i++){
scanf("%d%d%lld",&c,&d,&f);
addedge(c,d,f);
addedge(d,c,f);
}
ans=0;
dfs1(1,0);
dfs2(1,0,0,0);
printf("%lld\n",ans);
}
return 0;
}

hdu5886Tower Defence(树形dp)的更多相关文章

  1. poj3417 LCA + 树形dp

    Network Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4478   Accepted: 1292 Descripti ...

  2. COGS 2532. [HZOI 2016]树之美 树形dp

    可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...

  3. 【BZOJ-4726】Sabota? 树形DP

    4726: [POI2017]Sabota? Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 128  Solved ...

  4. 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)

    题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...

  5. 树形DP

    切题ing!!!!! HDU  2196 Anniversary party 经典树形DP,以前写的太搓了,终于学会简单写法了.... #include <iostream> #inclu ...

  6. BZOJ 2286 消耗战 (虚树+树形DP)

    给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...

  7. POJ2342 树形dp

    原题:http://poj.org/problem?id=2342 树形dp入门题. 我们让dp[i][0]表示第i个人不去,dp[i][1]表示第i个人去 ,根据题意我们可以很容易的得到如下递推公式 ...

  8. hdu1561 The more, The Better (树形dp+背包)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1561 思路:树形dp+01背包 //看注释可以懂 用vector建树更简单. 代码: #i ...

  9. bzoj2500: 幸福的道路(树形dp+单调队列)

    好题.. 先找出每个节点的树上最长路 由树形DP完成 节点x,设其最长路的子节点为y 对于y的最长路,有向上和向下两种情况: down:y向子节点的最长路g[y][0] up:x的次长路的g[x][1 ...

随机推荐

  1. 初识sa-token,一行代码搞定登录授权!

    前言 在java的世界里,有很多优秀的权限认证框架,如Apache Shiro.Spring Security 等等.这些框架背景强大,历史悠久,其生态也比较齐全. 但同时这些框架也并非十分完美,在前 ...

  2. 【Oracle】10g 11g下载路径

    现在直接点击不能下载了 要经过oracle许可才可以下载 如果嫌麻烦可以用迅雷直接下载密码是这个 一般不会动了 大家也不用帮我找回密码了 每次都改 也很麻烦的用迅雷下就不用密码了 下载也不会卡到最后 ...

  3. leetcode 321. 拼接最大数(单调栈,分治,贪心)

    题目链接 https://leetcode-cn.com/problems/create-maximum-number/ 思路: 心都写碎了.... 也许就是不适合吧.... 你是个好人... cla ...

  4. LeetCode454. 四数相加 II

    题目 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0. 分析 关键是如何想到用 ...

  5. Leetcode53. 最大子序列和

    问题 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. 代码 贪心算法 核心思想就是检查之前 i-1 的元素和,如果小于零就舍弃--对应下面第六行 ...

  6. online创建索引中途取消导致索引无法删除解决办法

    问题:有一个表ID栏位没有索引,但是在一个update语句的where中被使用,因此打算online创建索引,但是长时间没有成功,此时决定取消,取消后发现索引无法删除 过程: 数据库监控报警有行锁,进 ...

  7. missing tables and indexes的处理办法

    最近做了SAP系统的异构迁移,顺便把oracle DB也升级了,从10g升级到11g,但是升级后,在DB02或者是ora_space中的diagnostics->Missing Tables a ...

  8. MySQL索引性能分析

    为什么要做性能分析 你有没有这样的情况. 面对一个你没怎么写过的.复杂的业务,你构思了很久,终于开始敲下了第一段代码. 写的过程迷迷糊糊,有的时候还能把自己搞晕了. 但你还是终于把它写完了. 但是点击 ...

  9. ThreadLocal 原理分析

    用法 ThreadLocal<String> threadLocal = new ThreadLocal<>(); // 无初始值 ThreadLocal<String& ...

  10. MySQL 5.6.35 索引优化导致的死锁案例解析

    一.背景 随着公司业务的发展,商品库存从商品中心独立出来成为一个独立的系统,承接主站商品库存校验.订单库存扣减.售后库存释放等业务.在上线之前我们对于核心接口进行了压测,压测过程中出现了 MySQL ...