UESTC_酱神的旅行 2015 UESTC Training for Dynamic Programming<Problem M>
M - 酱神的旅行
Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)
酱神要去一棵树上旅行。
酱神制定了一个旅行计划,他要按顺序去m个树上的结点,a1,a2,a3,...,am。
酱神有一辆车,树上的每一条边既可以开车通过,也可以走过去,两种方法需要不同的时间。如果选择走路,酱神需要先把车停在结点上,在他下一次要开车的时候,必须先回到停车的结点取车。
酱神和他的爱车一开始都在a1结点上,酱神要依次访问完这m个结点最少需要多少时间。
Input
第一行两个数n,m。
1=<n,m<=5000
接下来n−1行,每行4个数,u,v,walk,drive。表示结点u和结点v之间有一条走路耗时为walk,开车耗时为drive的边。
1=<u,v<=n
1=<walk,drive<=109
最后输入m个数,a1,a2,a3,...,am, 酱神要按顺序访问的结点。
1=<ai<=n
Output
输出一个数,酱神的最小耗时。
Sample input and output
| Sample Input | Sample Output |
|---|---|
2 2 |
3 |
4 4 |
23 |
解题报告:
注意到树上两个点之间的路径是唯一的,且访问点的顺序是固定的,也就是说,经过的点的顺序是固定的,于是我们不妨令
dp(i , j )表示在路径在的第 i 个点,且是否有车的最小花费( 0 -> 无车 , 1 -> 有车 )
dp(cur , 0 ) = min ( dp( cur^1 , 0 ) , dp( cur^1 , 1 ) ) + walk_cost( i -> i + 1) )
è 直接走路过来 / 把车停在上一个点
dp(cur , 1 ) = min ( dp( cur^1 , 1 ) + car_cost(i -> i + 1) , f[r] + sum[i] ) -> r = a[i]
-> 直接开车过来 / 原来车就停在这,现在回来取(维护走路长度的前缀和)
-> f[r] = min( f[r] , dp(cur , 1) - sum[ cur ^ 1 ] );
注意到本题时限的原因,每次调用无根树转有根树时,需用BFS实现
若需要进一步降低时限,可使用LCA的离线算法,可将复杂度降低至O(N + Q),求路径上的点就不再累述.
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#define pb push_back
typedef long long ll;
const int maxn = 5e3 + ;
const ll inf = ;
using namespace std;
int n,m,prenode[maxn],cur = ,h[maxn],passnode[maxn],size,pretarget,target;
ll dp[][],f[maxn],sum[],walkdis[maxn],cardis[maxn]; typedef struct Edge
{
int target,walk,drive;
Edge(const int & target, const int & walk , const int & drive)
{
this->target = target , this->walk = walk , this->drive = drive;
}
}; vector<Edge>E[maxn]; typedef struct status
{
int pos,fat;
}; //无根树转有根树,BFS实现(比递归快 20 % )
inline void init_prenode(int pos)
{
status q[maxn*];
register int front = , rear = ;
q[rear].pos = pos , q[rear++].fat = ;
while(front < rear)
{
int thispos = q[front].pos;
int thisfat = q[front].fat;
prenode[thispos] = thisfat;
for(int i = ; i < E[thispos].size() ; ++ i)
{
int nextnode = E[thispos][i].target;
if (nextnode != thisfat)
{
if (prenode[nextnode] == thispos) continue; //剪枝
q[rear].pos = nextnode , q[rear++].fat = thispos;
}
else
walkdis[thisfat] = E[thispos][i].walk , cardis[thisfat] = E[thispos][i].drive;
}
++front;
}
} inline void add_nodes()
{
int k = prenode[pretarget];
while(k)
{
passnode[size++] = k;
k = prenode[k];
}
} int main(int argc,char *argv[])
{
int st;
scanf("%d%d",&n,&m);
for(int i = ; i < n - ; ++ i)
{
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
E[a].pb(Edge(b,c,d));
E[b].pb(Edge(a,c,d));
}
for(int i = ; i <= ; ++ i)
f[i] = inf;
memset(dp,,sizeof(dp));
memset(sum,,sizeof(sum));
memset(prenode,,sizeof(prenode));
memset(cardis,,sizeof(cardis));
memset(walkdis,,sizeof(walkdis));
size = ;
dp[cur][] = inf;
dp[cur][] = ;
if (m == )
{
printf("0\n");
return ;
}
scanf("%d",&pretarget);
init_prenode(pretarget);
for(int times = ; times < m ; ++ times)
{
scanf("%d",&target);
size = ;
init_prenode(target);
add_nodes();
for(int i = ; i < size ; ++ i)
{
cur ^= ;
int r = passnode[i];
sum[cur] = sum[cur^] + walkdis[r];
dp[cur][] = min(dp[cur^][] , dp[cur^][]) + walkdis[r];
dp[cur][] = min( dp[cur^][] + cardis[r] , f[r] + sum[cur]);
f[r] = min(f[r] , dp[cur][] - sum[cur]);
}
pretarget = target;
}
printf("%lld\n",min(dp[cur][],dp[cur][]));
return ;
}
UESTC_酱神的旅行 2015 UESTC Training for Dynamic Programming<Problem M>的更多相关文章
- UESTC_酱神赏花 2015 UESTC Training for Dynamic Programming<Problem C>
C - 酱神赏花 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 262143/262143KB (Java/Others) Submi ...
- UESTC_男神的约会 2015 UESTC Training for Dynamic Programming<Problem J>
J - 男神的约会 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit ...
- UESTC_男神的礼物 2015 UESTC Training for Dynamic Programming<Problem A>
A - 男神的礼物 Time Limit: 3000/3000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit ...
- UESTC_邱老师选妹子 2015 UESTC Training for Dynamic Programming<Problem H>
H - 邱老师选妹子 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submi ...
- UESTC_邱老师看电影 2015 UESTC Training for Dynamic Programming<Problem F>
F - 邱老师看电影 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submi ...
- UESTC_邱老师玩游戏 2015 UESTC Training for Dynamic Programming<Problem G>
G - 邱老师玩游戏 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submi ...
- UESTC_酱神寻宝 2015 UESTC Training for Dynamic Programming<Problem O>
O - 酱神寻宝 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit ...
- UESTC_邱老师选妹子(二) 2015 UESTC Training for Dynamic Programming<Problem I>
I - 邱老师选妹子(二) Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Su ...
- UESTC_导弹拦截 2015 UESTC Training for Dynamic Programming<Problem N>
N - 导弹拦截 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit ...
随机推荐
- 给Eclipse安装Google app engine插件
1.一般的做法: 参考:https://developers.google.com/eclipse/docs/install-eclipse-4.3 2. 因为 上面的做法一直没有成功,改为下载离线包 ...
- PHP初识
1. php是一种跨平台的语言,支持几乎全部的数据库. 以前觉得PHP与MYSQL是黄金组合,对于PHP能否支持MSSQL没有过了解,PHP支持几乎全部的数据库,也支持MSSQL(5.2.X版本可以用 ...
- UITableView 滚动时隐藏键盘
#pragma mark - UItableView滚动时收键盘 - (void)scrollViewWillBeginDragging:(UITableView *)scrollView { [se ...
- Android学习总结——实时显示系统时间
我们都知道System.currentTimeMillis()可以获取系统当前的时间,这里要实时显示就可以开启一个线程,然后通过handler发消息,来实时的更新TextView上显示的系统时间.具体 ...
- java类加载器行为[笔记]
1. Java虚拟机使用第一个类的第一件事情就是将该类的字节码装进来,装载类字节码的功能是由类装器完成的,类半遮器负责根据一个类的名称来定位和生成类的字节码数据后返回给Java虚拟机. 2. 类装载器 ...
- jquery在火狐浏览中上传图片并显示
由于火狐浏览器有很多代码无法兼容,特别是图片的显示,下面我介绍一种是我亲自测试过可以实现的方法 <script> function setImagePreview() { //var ix ...
- 1207.1——C语言 函数
函数可以分为无参函数和有参函数. 无参函数的定义 无参函数定义的一般形式如下:返回值类型 函数名(){ 函数体} 说明: 返回值类型可以是C语言中的任意数据类型. 函数名是标识符的一种,命名规 ...
- Qt模型/视图、委托
MVC视图和控制器对象相结合,其结果是模型/视图结构,仍然分离了数据与呈现给用户的方式,使得它可以在几个不同的视图中显示相同的数据,并实现新类型的视图而无需改变底层的数据结构.为了灵活的处理数据输入, ...
- 用实例一步步教你写Jquery插件
最近Web应用程序中越来越多地用到 了JQuery等Web前端技术.这些技术框架有效地改善了用户的操作体验,同时也提高了开发人员构造丰富客户 端UI的效率.JQuery本身提供了丰富的操作,但是,有时 ...
- JuPyter(IPython) Notebook中通过pip安装第三方Python Module
JuPyter(IPython) Notebooks中使用pip安装Python的模块 刚开始接触JuPyter Notebook的时候觉得这是个不错的写技术博客的工具,可以很直观的把代码和结果结合在 ...