Description

在山上一共有N个站点需要检查,检查员从山顶出发去各个站点进行检查,各个站点间有且仅有一条通路,检查员下山前往站点时比较轻松,而上山时却需要额外的时间,问最后检查员检查完所有站点时所需要的额外时间最少是多少。

Input

包含多组数据 每组数据输入第一行为一个整数N 表示站点个数(1<=N<=100000),接下去N-1 行 每行3个整数 x,y,z(1<=z<=10000) 检查站x为检查站y的父节点,x,y之间有一条通路,从y到x需要额外z的时间。(父节点在子节点上方,山顶固定标号为1)

Output

输出一行一个整数表示最少需要花费的额外时间。

Sample Input

6

1 2 1

2 4 1

1 3 1

3 5 1

3 6 1

Sample Output

3

题目乍一看像旅行商问题,但是n这么大,显然不是这么玩的。

考虑到树形结构的特殊性,就是从左子树到右子树,一定要进过父节点才能到达,这点是跟图不一样的。

于是从过程来看,我如果设p[i]表示遍历以i为根的子树所需的最小花费。all[i]表示遍历完并回到i结点的最小花费。当然,起始都是从i结点出发。

那么对于i来说,all[i] = sum(all[k]+dis[k][i])(k是i的子节点)

p[i] = min(sum(all[k]+dis[k][i])+p[j])(其中k != j)

这样的话,用记忆化搜索,便可以得到所有的p和all。p[1]即为所要求。

复杂度是O(n)

但是直接从结果上来看的话,整个遍历的路径,一定是每个线段都一上一下各一次,但是有一条从根部到底部的路径只下不上。(这个从之前的特殊性前提也可以推来)

这样便只需要找这样一条耗费最大的路径,然后用所有路径的和减去它即可。

复杂度也是O(n),但是可以省掉两个数组。

代码:(dp)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <algorithm>
#define LL long long using namespace std; const int maxN = 1e5+;
int n;
LL all[maxN], p[maxN]; inline LL myMin(LL x, LL y)
{
if (x == -)
return y;
else
return x < y ? x : y;
} //链式前向星
struct Edge
{
int to, next;
int val;
}edge[maxN]; int head[maxN], cnt; void addEdge(int u, int v, int val)
{
edge[cnt].to = v;
edge[cnt].val = val;
edge[cnt].next = head[u];
head[u] = cnt;
cnt++;
} void initEdge()
{
memset(head, -, sizeof(head));
cnt = ;
} void input()
{
initEdge();
memset(all, -, sizeof(all));
memset(p, -, sizeof(p));
int x, y, z;
for (int i = ; i < n; ++i)
{
scanf("%d%d%d", &x, &y, &z);
addEdge(x, y, z);
}
} void dfs(int now)
{
LL s = ;
int to;
for (int k = head[now]; k != -; k = edge[k].next)
{
to = edge[k].to;
if (all[to] == -)
dfs(to);
s += all[to]+edge[k].val;
}
all[now] = s;
for (int k = head[now]; k != -; k = edge[k].next)
{
to = edge[k].to;
p[now] = myMin(p[now], s-all[to]-edge[k].val+p[to]);
}
if (p[now] == -)
p[now] = ;
} void work()
{
dfs();
printf("%I64d\n", p[]);
} int main()
{
//freopen("test.in", "r", stdin);
while (scanf("%d", &n) != EOF)
{
input();
work();
}
return ;
}

ACM学习历程—FZU2195 检查站点(树形DP || 贪心)的更多相关文章

  1. ACM学习历程—HDU 1059 Dividing(dp && 多重背包)

    Description Marsha and Bill own a collection of marbles. They want to split the collection among the ...

  2. ACM学习历程—ZOJ3471 Most Powerful(dp && 状态压缩 && 记忆化搜索 && 位运算)

    Description Recently, researchers on Mars have discovered N powerful atoms. All of them are differen ...

  3. ACM学习历程—HDU1003 Max Sum(dp && 最大子序列和)

    Description Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum of a sub ...

  4. ACM学习历程—HDU4415 Assassin’s Creed(贪心)

    Problem Description Ezio Auditore is a great master as an assassin. Now he has prowled in the enemie ...

  5. ACM学习历程——HDU 5014 Number Sequence (贪心)(2014西安网赛)

    Description There is a special number sequence which has n+1 integers. For each number in sequence, ...

  6. ACM学习历程——POJ 1700 Crossing River(贪心)

    Description A group of N people wishes to go across a river with only one boat, which can at most ca ...

  7. ACM学习历程——POJ 2376 Cleaning Shifts(贪心)

    Description Farmer John is assigning some of his N (1 <= N <= 25,000) cows to do some cleaning ...

  8. 【bzoj4027】[HEOI2015]兔子与樱花 树形dp+贪心

    题目描述 很久很久之前,森林里住着一群兔子.有一天,兔子们突然决定要去看樱花.兔子们所在森林里的樱花树很特殊.樱花树由n个树枝分叉点组成,编号从0到n-1,这n个分叉点由n-1个树枝连接,我们可以把它 ...

  9. [BZOJ1596] [Usaco2008 Jan]电话网络(树形DP || 贪心)

    传送门 1.树形DP #include <cstdio> #include <cstring> #include <iostream> #define N 1000 ...

随机推荐

  1. c# 当前不会命中断点 未载入该文档

    C#编码时.有时会遇到标题所说的问题,就是说这个文件和方法明明存在,可总是提示找不到方法.解决方法例如以下: 1.清理全部项目(或相关项目)生成 2.又一次加入全部项目(或相关项目)间的互相引用 3. ...

  2. 修改Jmeter配置使能支持更大并发

    Jmeter做并发测试时,报错 java.lang.OutOfMemoryError:gc overhead limit exceeded. 原因是jmeter默认分配内存的参数很小,256M吧.故而 ...

  3. linux下jdk多版本管理

    linux下jdk多版本管理 项目开发中,不管是哪种语言都避免不了多个版本环境管理问题(本文虽然以jdk为例来写的,但不仅限于jdk),如何能做到快速的环境升级与切换确实是一件深思的事! 安装jdk ...

  4. java拾遗1----XML解析(一) DOM解析

    XML解析技术主要有三种: (1)DOM(Document Object Model)文档对象模型:是 W3C 组织推荐的解析XML 的一种方式,即官方的XML解析技术. (2)SAX(Simple ...

  5. js打开新窗口: window.open

    var iWidth = 800; var iHeight = 600; var iLeft = (window.screen.width - 10 - iWidth) / 2; //获得窗口的水平位 ...

  6. JVM类加载流程

    1.加载 a.装载类的第一个阶段 b.取得类的二进制流 c.转为方法区数据结构 d.在Java堆中生成对应的java.lang.Class对象 2.链接 a.验证(保证Class流的格式是正确的) 文 ...

  7. scala与java之间的那些事

    scala与java之间的关系,我认为可以用一句话来开头:scala来源于java,但又高于java. scala的设计者Martin Odersky就是一个JAVA控,这位牛人设计了javac和编写 ...

  8. C#与数据库连接简单测试

    效果展示   数据库代码 create database OneDb go USE OneDb; GO CREATE TABLE classify --分类表 ( id ,), name ) not ...

  9. sonarQube使用maven进行检查

    1.在maven的中找到setting配置文件.在setting.xml中增加sonarqube配置.如下: <profiles> <profile> <id>so ...

  10. 自定义xhr请求

    接上一篇博客,上一篇是之前的jsonp请求方法的封装,这一篇是xhr请求的简单封装. 原理: 1:new一个xhr对象,命名为ajaxRequest,由于浏览器兼容性的问题,所以将获取xhr对象的方式 ...