数据结构(左偏树,可并堆):BNUOJ 3943 Safe Travel
Safe Travel
64-bit integer IO format: %lld Java class name: Main
Each of the cows, of course, wishes not to be harassed and thus chooses an at least slightly different route from pasture_1 (the barn) to pasture_i.
Compute the best time to traverse each of these new not-quite-quickest routes that enable each cow_i that avoid gremlin_i who is located on the final cowpath of the quickest route from pasture_1 to pasture_i.
As usual, the M (2 <= M <= 200,000) cowpaths conveniently numbered 1..M are bidirectional and enable travel to all N (3 <= N <= 100,000) pastures conveniently numbered 1..N. Cowpath i connects pastures a_i (1 <= a_i <= N) and b_i (1 <= b_i <= N) and requires t_i (1 <= t_i <= 1,000) time to traverse. No two cowpaths connect the same two pastures, and no path connects a pasture to itself (a_i != b_i).
Best of all, the shortest path regularly taken by cow_i from pasture_1 to pasture_i is unique in all the test data supplied to your program.
By way of example, consider these pastures, cowpaths, and [times]:
1----[2]----2---+
| | |
[2] [1] [3]
| | |
+-----3---[4]---4
TRAVEL BEST ROUTE BEST TIME LAST PATH
p_1 to p_2 1->2 2 1->2
p_1 to p_3 1->3 2 1->3
p_1 to p_4 1->2->4 5 2->4
When gremlins are present:
TRAVEL BEST ROUTE BEST TIME AVOID
p_1 to p_2 1->3->2 3 1->2
p_1 to p_3 1->2->3 3 1->3
p_1 to p_4 1->3->4 6 2->4
Input
* Lines 2..M+1: Three space-separated integers: a_i, b_i, and t_i
Output
Sample Input
4 5
1 2 2
1 3 2
3 4 4
3 2 1
2 4 3
Sample Output
3
3
6
这道题是世界上第一道树链剖分的题目,我用左偏树AC了。
考虑先建一棵最短路树,一个点去掉树边后,它到根节点的距离就由它的子节点和它自己由非树边连到它这棵子树外的节点来更新,可以维护可并堆。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
const int maxn=;
const int maxm=;
int cnt,fir[maxn],to[maxm],nxt[maxm],val[maxm];
void addedge(int a,int b,int c){
nxt[++cnt]=fir[a];to[cnt]=b;fir[a]=cnt;val[cnt]=c;
} int tot,rt[maxm],key[maxm],lik[maxm],ch[maxm][],dep[maxm];
int ans[maxn],dis[maxn],add[maxm]; void Add(int x,int d){
if(!x)return;
key[x]+=d;
add[x]+=d;
} void Push_down(int x){
Add(ch[x][],add[x]);
Add(ch[x][],add[x]);
add[x]=;
} int Merge(int x,int y){
if(!x||!y)return x|y;
if(key[x]>key[y])swap(x,y);
Push_down(x);
ch[x][]=Merge(ch[x][],y);
if(dep[ch[x][]]<dep[ch[x][]])
swap(ch[x][],ch[x][]);
dep[x]=dep[ch[x][]]+;
return x;
} void Delete(int node){
Push_down(rt[node]);
rt[node]=Merge(ch[rt[node]][],ch[rt[node]][]);
} int ID[maxn],end[maxn],id; void DFS(int node){
ID[node]=++id;
for(int i=fir[node];i;i=nxt[i])
if(dis[to[i]]==dis[node]+val[i])
DFS(to[i]);
end[node]=id;
} void Solve(int node){
for(int i=fir[node];i;i=nxt[i]){
if(dis[to[i]]==dis[node]+val[i]){
Solve(to[i]);
Add(rt[to[i]],val[i]);
rt[node]=Merge(rt[node],rt[to[i]]);
}
else{
if(dis[to[i]]+val[i]==dis[node])continue;
if(ID[to[i]]<=end[node]&&ID[to[i]]>=ID[node])continue;
key[++tot]=dis[to[i]]+val[i];lik[tot]=to[i];
rt[node]=Merge(rt[node],tot);
}
}
while(rt[node]&&ID[lik[rt[node]]]<=end[node]&&ID[lik[rt[node]]]>=ID[node]){
Delete(node);
}
if(rt[node])
ans[node]=key[rt[node]];
}
struct Node{
int d,n;
Node(int d_=,int n_=){
d=d_;n=n_;
}
bool operator <(const Node &b)const{
return d>b.d;
}
}; priority_queue <Node,vector<Node> >q; int main(){
freopen("travel.in","r",stdin);
freopen("travel.out","w",stdout);
int n,m;
dep[]=-;
scanf("%d%d",&n,&m);
for(int i=,a,b,c;i<=m;i++){
scanf("%d%d%d",&a,&b,&c);
addedge(a,b,c);
addedge(b,a,c);
}
memset(dis,,sizeof(dis));
q.push(Node(,));dis[]=;
while(!q.empty()){
Node x=q.top();q.pop();
for(int i=fir[x.n];i;i=nxt[i]){
if(dis[x.n]+val[i]<dis[to[i]]){
dis[to[i]]=dis[x.n]+val[i];
q.push(Node(dis[to[i]],to[i]));
}
}
}
DFS();
Solve();
for(int i=;i<=n;i++)
printf("%d\n",ans[i]==?-:ans[i]);
return ;
}
数据结构(左偏树,可并堆):BNUOJ 3943 Safe Travel的更多相关文章
- bzoj2809 [Apio2012]dispatching——左偏树(可并堆)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2809 思路有点暴力和贪心,就是 dfs 枚举每个点作为管理者: 当然它的子树中派遣出去的忍者 ...
- [note]左偏树(可并堆)
左偏树(可并堆)https://www.luogu.org/problemnew/show/P3377 题目描述 一开始有N个小根堆,每个堆包含且仅包含一个数.接下来需要支持两种操作: 操作1: 1 ...
- HDU3031 To Be Or Not To Be 左偏树 可并堆
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - HDU3031 题意概括 喜羊羊和灰太狼要比赛. 有R次比赛. 对于每次比赛,首先输入n,m,n表示喜羊羊和灰 ...
- HDU5818 Joint Stacks 左偏树,可并堆
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - HDU5818 题意概括 有两个栈,有3种操作. 第一种是往其中一个栈加入一个数: 第二种是取出其中一个栈的顶 ...
- BZOJ 4003: [JLOI2015]城池攻占 左偏树 可并堆
https://www.lydsy.com/JudgeOnline/problem.php?id=4003 感觉就是……普通的堆啊(暴论),因为这个堆是通过递归往右堆里加一个新堆或者新节点的,所以要始 ...
- Monkey King(左偏树 可并堆)
我们知道如果要我们给一个序列排序,按照某种大小顺序关系,我们很容易想到优先队列,的确很方便,但是优先队列也有解决不了的问题,当题目要求你把两个优先队列合并的时候,这就实现不了了 优先队列只有插入 删除 ...
- BZOJ 5494: [2019省队联测]春节十二响 (左偏树 可并堆)
题意 略 分析 稍微yy一下可以感觉就是一个不同子树合并堆,然后考场上写了一发左偏树,以为100分美滋滋.然而发现自己傻逼了,两个堆一一对应合并后剩下的一坨直接一次合并进去就行了.然鹅我这个sb把所有 ...
- [luogu3377][左偏树(可并堆)]
题目链接 思路 左偏树的模板题,参考左偏树学习笔记 对于这道题我是用一个并查集维护出了哪些点是在同一棵树上,也可以直接log的往上跳寻找根节点 代码 #include<cstdio> #i ...
- BZOJ1455 罗马游戏 左偏树 可并堆
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1455 题意概括 n个人,2种操作. 一种是合并两个人团,一种是杀死某一个人团的最弱的人. 题解 左 ...
随机推荐
- Oracle数据库管理员经常使用的表和视图
◆dba_开头 dba_users 数据库用户信息 dba_segments 表段信息 dba_extents 数据区信息 dba_objects 数据库对象信息 dba_tablespaces 数据 ...
- 2017JAVA必读书籍
1.深入理解Java虚拟机:JVM高级特性与最佳实践 2.Oracle查询优化改写技巧与案例 3.Effective Java 4.Spring3.x企业应用开发实战 5.Spring技术内幕:深入解 ...
- aliyun云服务器硬件性能测试
1.所购买阿里云服务器信息 2.dd命令测试 3.
- copssh加bitvise
只是简单记录下自己在成功使用的方案: 目的:为了突破公司对网站和qq的限制 具备的条件:一台云服务器.Copssh_4.1.0.bitvise ssh client 4.62.公司电脑客户端 一.首先 ...
- wpf 调用线程必须为sta 因为许多ui组件都需要
解决 办法 public void SomeMethod() { var task = System.Windows.Application.Current.Dispatcher.BeginInvok ...
- 使用AutoMapper实现Dto和Model之间自由转换
应用场景:一个Web应用通过前端收集用户的输入成为Dto,然后将Dto转换成领域模型并持久化到数据库中.另一方面,当用户请求数据时,我们又需要做相反的工作:将从数据库中查询出来的领域模型以相反的方式转 ...
- 最简单的基于FFmpeg的移动端例子:IOS 推流器
转至:http://blog.csdn.net/leixiaohua1020/article/details/47072519 ================================== ...
- 完整的 dataType=text/plain jquery ajax 登录验证
Html: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <m ...
- SGU 185.Two shortest (最小费用最大流)
时间限制:0.25s 空间限制:4M 题意: 在n(n<=400)个点的图中,找到并输出两条不想交的最短路.不存在输出“No sulotion”: Solution: 最小费用最大流 建图与po ...
- Android开发系列----学习伊始
因为对移动端开发开始感兴趣,开始学习App开发,没有苹果环境的我,只好先选择Android来玩一玩了~~ 找了一套视频,买了几本java.android开发的书,开始搞起~~