Safe Travel

Time Limit: 3000ms
Memory Limit: 65536KB

64-bit integer IO format: %lld      Java class name: Main

  Gremlins have infested the farm. These nasty, ugly fairy-like creatures thwart the cows as each one walks from the barn (conveniently located at pasture_1) to the other fields, with cow_i traveling to from pasture_1 to pasture_i. Each gremlin is personalized and knows the quickest path that cow_i normally takes to pasture_i. Gremlin_i waits for cow_i in the middle of the final cowpath of the quickest route to pasture_i, hoping to harass cow_i.

  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

  * Line 1: Two space-separated integers: N and M

  * Lines 2..M+1: Three space-separated integers: a_i, b_i, and t_i

 

Output

  * Lines 1..N-1: Line i contains the smallest time required to travel from pasture_1 to pasture_i+1 while avoiding the final cowpath of the shortest path from pasture_1 to pasture_i+1. If no such path exists from pasture_1 to pasture_i+1, output -1 alone on the line.

 

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的更多相关文章

  1. bzoj2809 [Apio2012]dispatching——左偏树(可并堆)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2809 思路有点暴力和贪心,就是 dfs 枚举每个点作为管理者: 当然它的子树中派遣出去的忍者 ...

  2. [note]左偏树(可并堆)

    左偏树(可并堆)https://www.luogu.org/problemnew/show/P3377 题目描述 一开始有N个小根堆,每个堆包含且仅包含一个数.接下来需要支持两种操作: 操作1: 1 ...

  3. HDU3031 To Be Or Not To Be 左偏树 可并堆

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - HDU3031 题意概括 喜羊羊和灰太狼要比赛. 有R次比赛. 对于每次比赛,首先输入n,m,n表示喜羊羊和灰 ...

  4. HDU5818 Joint Stacks 左偏树,可并堆

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - HDU5818 题意概括 有两个栈,有3种操作. 第一种是往其中一个栈加入一个数: 第二种是取出其中一个栈的顶 ...

  5. BZOJ 4003: [JLOI2015]城池攻占 左偏树 可并堆

    https://www.lydsy.com/JudgeOnline/problem.php?id=4003 感觉就是……普通的堆啊(暴论),因为这个堆是通过递归往右堆里加一个新堆或者新节点的,所以要始 ...

  6. Monkey King(左偏树 可并堆)

    我们知道如果要我们给一个序列排序,按照某种大小顺序关系,我们很容易想到优先队列,的确很方便,但是优先队列也有解决不了的问题,当题目要求你把两个优先队列合并的时候,这就实现不了了 优先队列只有插入 删除 ...

  7. BZOJ 5494: [2019省队联测]春节十二响 (左偏树 可并堆)

    题意 略 分析 稍微yy一下可以感觉就是一个不同子树合并堆,然后考场上写了一发左偏树,以为100分美滋滋.然而发现自己傻逼了,两个堆一一对应合并后剩下的一坨直接一次合并进去就行了.然鹅我这个sb把所有 ...

  8. [luogu3377][左偏树(可并堆)]

    题目链接 思路 左偏树的模板题,参考左偏树学习笔记 对于这道题我是用一个并查集维护出了哪些点是在同一棵树上,也可以直接log的往上跳寻找根节点 代码 #include<cstdio> #i ...

  9. BZOJ1455 罗马游戏 左偏树 可并堆

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1455 题意概括 n个人,2种操作. 一种是合并两个人团,一种是杀死某一个人团的最弱的人. 题解 左 ...

随机推荐

  1. 10.18 noip模拟试题

    分火腿 (hdogs.pas/.c/.cpp) 时间限制:1s:内存限制 64MB 题目描述: 小月言要过四岁生日了,她的妈妈为她准备了n根火腿,她想将这些火腿均分给m位小朋友,所以她可能需要切火腿. ...

  2. 从创建webservice到发布webservice的一些相关总结

    最近做了一个web服务,开始什么也不懂,就在网上到处找,对于刚毕业的我,感觉没用实际代码经过自己的手写出来,看什么都一头雾水,然后就看到很多人说webservice已经融入WCF..然后就先创建了WC ...

  3. E/Trace: error opening trace file: No such file or directory

    E/Trace: error opening trace file: No such file or directory (2) 有这一个错误,想了一下,然后发现是 AdroidManifest.xm ...

  4. VS2015 Cordova Ionic移动开发(二)

    一.创建空白Cordova应用 打开VS,选择[新建项目],选择其它语言JavaScript或者TypeScript,语言的话就按个人喜好,喜欢JS就用JS,喜欢TS就用TS,推荐使用TS书写,代码结 ...

  5. WCF系列学习5天速成

    看到一篇比较好的基础wcf学习博客,分享给大家:http://www.cnblogs.com/huangxincheng/archive/2011/10/23/2221845.html

  6. Delphi ControlCount和ComponentCount的区别

    ComponentCount指打开的窗体所拥有的控件个数,包含所有子组件.孙组件(子组件内的子组件) 如上图,Form1的ComponentCount是13,而Panel1的ComponentCoun ...

  7. 342. Power of Four

    题目: Given an integer (signed 32 bits), write a function to check whether it is a power of 4. Example ...

  8. 330. Patching Array--Avota

    问题描述: Given a sorted positive integer array nums and an integer n, add/patch elements to the array s ...

  9. ZOJ 3872 Beauty of Array

    /** Author: Oliver ProblemId: ZOJ 3872 Beauty of Array */ /* 需求: 求beauty sum,所谓的beauty要求如下: 1·给你一个集合 ...

  10. javascript常用内置对象总结(重要)

    Javascript对象总结 JS中内置了17个对象,常用的是Array对象.Date对象.正则表达式对象.string对象.Global对象 Array对象中常用方法: Concat():表示把几个 ...