ACM学习历程—FZU2195 检查站点(树形DP || 贪心)
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 || 贪心)的更多相关文章
- ACM学习历程—HDU 1059 Dividing(dp && 多重背包)
Description Marsha and Bill own a collection of marbles. They want to split the collection among the ...
- ACM学习历程—ZOJ3471 Most Powerful(dp && 状态压缩 && 记忆化搜索 && 位运算)
Description Recently, researchers on Mars have discovered N powerful atoms. All of them are differen ...
- 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 ...
- ACM学习历程—HDU4415 Assassin’s Creed(贪心)
Problem Description Ezio Auditore is a great master as an assassin. Now he has prowled in the enemie ...
- ACM学习历程——HDU 5014 Number Sequence (贪心)(2014西安网赛)
Description There is a special number sequence which has n+1 integers. For each number in sequence, ...
- 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 ...
- ACM学习历程——POJ 2376 Cleaning Shifts(贪心)
Description Farmer John is assigning some of his N (1 <= N <= 25,000) cows to do some cleaning ...
- 【bzoj4027】[HEOI2015]兔子与樱花 树形dp+贪心
题目描述 很久很久之前,森林里住着一群兔子.有一天,兔子们突然决定要去看樱花.兔子们所在森林里的樱花树很特殊.樱花树由n个树枝分叉点组成,编号从0到n-1,这n个分叉点由n-1个树枝连接,我们可以把它 ...
- [BZOJ1596] [Usaco2008 Jan]电话网络(树形DP || 贪心)
传送门 1.树形DP #include <cstdio> #include <cstring> #include <iostream> #define N 1000 ...
随机推荐
- Solr6.5与mysql集成建立索引
首先在solrconfig.xml(我的是保存在/usr/local/tomcat/solrhome/mycore/conf/下)的<requestHandler name="/sel ...
- 在UIWebView中设置cookie
本文转载至 http://blog.csdn.net/chengyakun11/article/details/8863878 项目中,需要在打开3g网页时,通过cookie传递一些信息. 实现代码 ...
- TP框架的修改,删除
先把数据库的素具显示出来 public function xiugai() { $code= "n001";//修改的主键值 $n = M("nation"); ...
- poj3708(公式化简+大数进制装换+线性同余方程组)
刚看到这个题目,有点被吓到,毕竟自己这么弱. 分析了很久,然后发现m,k都可以唯一的用d进制表示.也就是用一个ai,和很多个bi唯一构成. 这点就是解题的关键了. 之后可以发现每次调用函数f(x),相 ...
- 【BZOJ3926】[Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机
[BZOJ3926][Zjoi2015]诸神眷顾的幻想乡 Description 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽香的2600岁生日,无数幽香的粉丝到了幽香家门前的太阳花田上来为幽香庆祝 ...
- Centos设置开机启动Apache和Mysql
先用chkconfig --list查询apache和mysql服务是否存在,不存在则需要手动添加 [root@centos64 vsftpd]# chkconfig --list 测试存在,只需要开 ...
- twig 截取字符串
<p>{{content|slice(0,100)}}</p> slice()截取content变量值,从0到100
- Docker学习总结之docker创建私有仓库(private Repositories)
Docker 创建 Private Repositories 前言 基于GFW的缘故,国内大陆基本无法pull国外的镜像,更别说官方的index了.如果images无法pull下来,那么docker就 ...
- 深度问答之提取语料,导入了yml模块
根据目录下的yml文件循环创建同名文件夹,并从yml文件读取问答并给每个文件夹写入question和answer文件 #!/usr/bin/env python # coding:utf8 # aut ...
- 【LeetCode】 数相加组合 Combination Sum
描述 Given a set of candidate numbers (candidates) (without duplicates) and a target number (target), ...