hihoCoder 1168 运输货物
来源:互联网 发布:mysql acos函数 编辑:程序博客网 时间:2024/04/28 12:35
#1168 : 运输货物
描述
Z国有n个城市,编号为1, 2, …, n。城市间通过n – 1条道路相连,任意两个城市间有且仅有一条路径可以相互到达。每个城市都有一些货物,政府希望将所有的货物运送到港口城市s以便出口。由于交通条件限制,每一条道路上单位时间只能通过1单位量的货物,这导致运输所有货物可能非常耗时。因而,政府希望知道,最快什么时候能将所有货物运送到港口。
输入
第一行一个整数T,表示数据组数,以下是T组数据。
每组数据第一行有两个整数n和s,表示城市个数和港口城市的编号。接下来n - 1行每行两个整数i和j,表示城市i和j之间有一条道路。接下来n行每行一个数x,表示各城市的货物数量。
输出
对每组数据输出一行"Case #X: Y",X表示数据编号(从1开始),Y为完成运输任务的最短时间。
数据范围
1 ≤ T ≤ 20
小数据
1 ≤ n ≤ 500
0 ≤ x ≤ 20
大数据
1 ≤ n ≤ 100000
0 ≤ x ≤ 100000
1.把货物的终点记作root,对于root的每一个孩子节点1,2,3....,求出.t1,t2,t3...。t1的含义是将货物从1及其子树运
往root所用的时间(1子树的上载时间),那么总时间便是max(t1,t2,t3...)
2.那么我们如何求t1呢,首先想,如果没有节点的货物量是0,就能保证每个边总是有货物需要运的,t1便是这些节点
货物量之和
3.但是如果某些节点的货量是0,那么有可能就出现边闲置的问题,(想一想为什么?)
4.怎么解决呢,如果我们暴力的解决,就是每一秒钟,枚举各节点货物量的变化,直到所有节点的值都为0
5.还可以这样想,把节点分层,(距离跟节点1条边,2条边。。。),每过一秒,就有下面一层的货物运向上面一层
6.
一条横线代表一层,考虑这棵树,标号代表城市的货物量,
第1秒,没有货物可以上载,出现空闲
第2秒,正好有一个货物可以上载,没有出现空闲
第3秒,可以上载
第4秒,出现空闲
第5,6秒,上载完成
总上载时间就是货物量+空闲的时间
7.空闲的时间的可以推断出,如果第i层没有货物,且0-i层没有排队延迟,就会导致空闲
8.算出每一层的排队延迟,再与没有货物的曾作比较,就可以算出最后的空闲时间了
总结:
1.感觉这个题目是真心很好,比赛结束1分钟的时候才改对这个题目,真是可惜,还需要提高速度啊
2.最近考试算法分析,再跟同学讨论动态规划的时候突然感悟,突然觉得动态规划很多时候就是对枚举的优化,记录
那些需要重复运算的点,避免不必要的操作。推广感觉很多题目都是这样的!
3.这个题目刚开始总猜dfs深搜来做,后来突然感悟用分层做出来的,总结下来的思考方式也是:从暴力枚举优化到
dfs预处理分层来做这个题
4.感悟很多,好题,还需要继续努力
#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>using namespace std;typedef long long LL;#define MAXN 100005int num[MAXN],first[MAXN],deepest,n,e,root,_;LL d[MAXN];struct Edge{ int v,next;}edge[MAXN << 1];void insert(int u,int v){ edge[e].next = first[u]; edge[e].v = v; first[u] = e++;}void dfs(int u,int fa,int deep){ if(num[u])deepest = max(deepest,deep); d[deep] += num[u]; for(int i = first[u];i != -1;i = edge[i].next) { int v = edge[i].v; if(v == fa)continue; dfs(v,u,deep + 1); }}int main(){ for(int kcas = scanf("%d",&_);kcas <= _;kcas++) { e = 0; memset(first,-1,sizeof(first)); memset(d,0x3f,sizeof(d)); scanf("%d%d",&n,&root); for(int i = 1;i < n;i++) { int u,v; scanf("%d%d",&u,&v); insert(u,v); insert(v,u); } for(int i = 1;i <= n;i++) scanf("%d",&num[i]); LL ans = 0; for(int i = first[root];i != -1;i = edge[i].next) { int v = edge[i].v; deepest = 0; memset(d,0,sizeof(d)); dfs(v,root,0); LL t1 = 0,t2 = 0; for(int i = 0;i <= deepest;i++) { t1 += d[i]; if(d[i] == 0 && t1 + t2 <= i) t2++; } ans = max(t1 + t2,ans); } printf("Case #%d: %lld\n",kcas,ans); }}
- hihoCoder 1168 运输货物
- hihocoder 1168 运输货物
- hihocoder #1168 : 运输货物
- 【IndiaHacks 2016 - Online Edition (Div 1 + Div 2) ErrichtoD】【二分答案 最大流】Delivery Bears x只熊运输同样的实物重量货物
- 货物管理
- 货物管理
- 运载货物
- 货物调度
- 搬货物
- hihocoder:
- hihoCoder
- Hihocoder
- hihocoder
- hihocoder
- hihocoder
- hihocoder
- hihocoder
- HihoCoder
- 执行Gradle clean命令后,报错:peer not authenticated
- Codeforces 543D Road Improvement 树形dp
- 生成链表
- 《一个阶段的结束是另一个阶段的开始--记这两个月以来的前端实习生面试》
- Java程序员常用工具集
- hihoCoder 1168 运输货物
- Crontab的格式
- thinkphp表单处理
- JavaScript三种弹出框(alert,confirm和prompt)用法举例
- Unity3D连接SQL Sever数据库
- cxGrid多选使用CheckBox cxGrid动态创建带CheckBox列时遇到的问题...
- 身份证号码的规则及验证原理
- NSNumber
- mysql 安装过程中碰到的一些问题