Codeforces787D(SummerTrainingDay06-D 线段树+最短路)
D. Legacy
Rick and his co-workers have made a new radioactive formula and a lot of bad guys are after them. So Rick wants to give his legacy to Morty before bad guys catch them.
There are n planets in their universe numbered from 1 to n. Rick is in planet number s (the earth) and he doesn't know where Morty is. As we all know, Rick owns a portal gun. With this gun he can open one-way portal from a planet he is in to any other planet (including that planet). But there are limits on this gun because he's still using its free trial.

By default he can not open any portal by this gun. There are q plans in the website that sells these guns. Every time you purchase a plan you can only use it once but you can purchase it again if you want to use it more.
Plans on the website have three types:
- With a plan of this type you can open a portal from planet v to planet u.
- With a plan of this type you can open a portal from planet v to any planet with index in range [l, r].
- With a plan of this type you can open a portal from any planet with index in range [l, r] to planet v.
Rick doesn't known where Morty is, but Unity is going to inform him and he wants to be prepared for when he finds and start his journey immediately. So for each planet (including earth itself) he wants to know the minimum amount of money he needs to get from earth to that planet.
Input
The first line of input contains three integers n, q and s (1 ≤ n, q ≤ 105, 1 ≤ s ≤ n) — number of planets, number of plans and index of earth respectively.
The next q lines contain the plans. Each line starts with a number t, type of that plan (1 ≤ t ≤ 3). If t = 1 then it is followed by three integers v, u and w where w is the cost of that plan (1 ≤ v, u ≤ n, 1 ≤ w ≤ 109). Otherwise it is followed by four integers v, l, r and w where w is the cost of that plan (1 ≤ v ≤ n, 1 ≤ l ≤ r ≤ n, 1 ≤ w ≤ 109).
Output
In the first and only line of output print n integers separated by spaces. i-th of them should be minimum money to get from earth to i-th planet, or - 1 if it's impossible to get to that planet.
Examples
input
3 5 1
2 3 2 3 17
2 3 2 2 16
2 2 2 3 3
3 3 1 1 12
1 3 3 17
output
0 28 12
input
4 3 1
3 4 1 3 12
2 2 3 4 10
1 2 4 16
output
0 -1 -1 12
Note
In the first sample testcase, Rick can purchase 4th plan once and then 2nd plan in order to get to get to planet number 2.
题意:有n个点,q个询问,每次询问有一种操作。操作1:u→[l,r](即u到l,l+1,l+2,...,r距离均为w)的距离为w;操作2:[l,r]→u的距离为w;操作3:u到v的距离为w;求起点到其他点的最短距离,到达不了输出-1。
思路:这道题目如果老老实实的去建图的话,边会多到爆炸。所以我们需要另外想一个建图方法。
由于边的起点或者终点涉及到了区间的情况,我们可以使用线段树建图的套路。
对于整段区间,我们用把它划分成一颗线段树。
对于整个图,我们可以构造两颗线段树A和B。
在A线段树上,我们从底部往上连权值为0的边。对于B线段树来说我们从顶部往下连边权值为0的边。
然后我们把B线段树底部的所有点向A线段树底部的点连权值为0得边。
对于type=1的边,我们从A线段树底部的点向B线段树底部的点做权值为w的边。
对于type=2的边,我们从A线段树底部的点向B线段树对应的区间段连权值为w的一些边。
对于type=3的边,我们从A线段树对应的区间段向B线段树底部对应的点连权值为w的一些边。
然后跑最短路就行了。
//2017-09-04
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#define ll long long
#define lson (id<<1)
#define rson ((id<<1)|1) using namespace std; const int N = ;
const ll INF = 0x3f3f3f3f3f3f3f3f; int head[N<<], tot;
struct Edge{
int to, w, next;
}edge[N<<]; void init(){
tot = ;
memset(head, -, sizeof(head));
} void add_edge(int u, int v, int w){
edge[tot].w = w;
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
} vector<int> vec;
int tree[][N<<], idx;
//k为0表示从顶向下的线段树
//k为1表示从底向上的线段树
void build(int id, int l, int r, int k){
tree[k][id] = ++idx;
if(l == r){
if(k == )
add_edge(tree[k][id], l, );
else
add_edge(l, tree[k][id], );
return;
}
int mid = (l+r)>>;
build(lson, l, mid, k);
build(rson, mid+, r, k);
if(k == ){
add_edge(tree[k][id], tree[k][lson], );
add_edge(tree[k][id], tree[k][rson], );
}else{
add_edge(tree[k][lson], tree[k][id], );
add_edge(tree[k][rson], tree[k][id], );
}
} //获得[L, R]区间对应的节点集合
//l,r为辅助变量,k表示操作第k棵线段树
void get_interval(int id, int l, int r, int L, int R, int k){
if(L <= l && r <= R){
vec.push_back(tree[k][id]);
return;
}
int mid = (l+r)>>;
if(mid >= L)
get_interval(lson, l, mid, L, R, k);
if(mid < R)
get_interval(rson, mid+, r, L, R, k);
} bool vis[N<<];
ll dis[N<<];
int cnt[N<<];
deque<int> dq; bool spfa(int s, int n){
memset(vis, , sizeof(vis));
memset(cnt, , sizeof(cnt));
for(int i = ; i <= n; i++)
dis[i] = INF;
vis[s] = ;
dis[s] = ;
cnt[s] = ;
deque<int> dq;
dq.push_back(s);
while(!dq.empty()){
int u = dq.front();
dq.pop_front();
vis[u] = ;
for(int i = head[u]; i != -; i = edge[i].next){
int v = edge[i].to;
if(dis[v] > dis[u] + edge[i].w){
dis[v] = dis[u] + edge[i].w;
if(!vis[v]){
vis[v] = ;
dq.push_back(v);
if(++cnt[v] > n)return false;
}
}
}
}
return true;
}
int main()
{
//freopen("inputD.txt", "r", stdin);
int n, q, s;
while(scanf("%d%d%d", &n, &q, &s) != EOF){
init();
idx = n;//线段树上表示区间的点从n+1开始
build(, , n, );
build(, , n, );
int l, r, v, w, u, t;
while(q--){
scanf("%d", &t);
if(t == ){
scanf("%d%d%d", &v, &u, &w);
add_edge(v, u, w);
}else if(t == ){
scanf("%d%d%d%d", &v, &l, &r, &w);
vec.clear();
get_interval(, , n, l, r, );
for(auto &u : vec)
add_edge(v, u, w);
}else if(t == ){
scanf("%d%d%d%d", &v, &l, &r, &w);
vec.clear();
get_interval(, , n, l, r, );
for(auto &u : vec)
add_edge(u, v, w);
}
}
spfa(s, *n);
for(int i = ; i <= n; i++)
if(dis[i] == INF)
printf("-1 ");
else printf("%I64d ", dis[i]);
printf("\n");
} return ;
}
Codeforces787D(SummerTrainingDay06-D 线段树+最短路)的更多相关文章
- Vijos 1404 遭遇战 - 动态规划 - 线段树 - 最短路 - 堆
背景 你知道吗,SQ Class的人都很喜欢打CS.(不知道CS是什么的人不用参加这次比赛). 描述 今天,他们在打一张叫DUSTII的地图,万恶的恐怖分子要炸掉藏在A区的SQC论坛服务器!我们SQC ...
- Codeforces 787D Legacy 线段树 最短路
题意: 有\(n(1 \leq n \leq 10^5)\)个点,\(q(1 \leq q \leq 10^5)\)条路和起点\(s\) 路有三种类型: 从点\(v\)到点\(u\)需要花费\(w\) ...
- 786B - Legacy(线段树 + 最短路)线段树优化建图
题意: 就是给定一张n nn个点的图,求源点s ss到每个点的单源最短路.这张图共有q组边,连边方式有3种: a→b ,边权为w的单向边:a→[l,r] ,即a到连续区间[l,r]中的每一个点都有一条 ...
- HDU5361 In Touch(线段树 + 最短路)
传送门 恰逢才做过VFK的A+B Problem,发现这道题也可以那样搞.区间连边的时候,我们就可以给那个区间在线段树对应的标号上连边. 线段树也可以不建出来,直接当做一个标号的合集,不占用内存,只用 ...
- CodeForces786B 线段树 + 最短路
给定n颗行星,q次处理,地球位置为s,求解在q次处理后,地球到每一颗行星的位置. 其中q有三种不同的操作: 输入v,u,wv,u,w,构建一条从vv到uu的代价为ww的路线 输入u,l,r,wu,l, ...
- B - Legacy CodeForces - 787D 线段树优化建图+dij最短路 基本套路
B - Legacy CodeForces - 787D 这个题目开始看过去还是很简单的,就是一个最短路,但是这个最短路的建图没有那么简单,因为直接的普通建图边太多了,肯定会超时的,所以要用线段树来优 ...
- HDU 5669 线段树优化建图+分层图最短路
用线段树维护建图,即把用线段树把每个区间都标号了,Tree1中子节点有到达父节点的单向边,Tree2中父节点有到达子节点的单向边. 每次将源插入Tree1,汇插入Tree2,中间用临时节点相连.那么T ...
- HDU5669 Road 分层最短路+线段树建图
分析:(官方题解) 首先考虑暴力,显然可以直接每次O(n^2) 的连边,最后跑一次分层图最短路就行了. 然后我们考虑优化一下这个连边的过程 ,因为都是区间上的操作,所以能够很明显的想到利用线段树来维 ...
- 最短路 BZOJ3694 树链剖分+线段树
分析: 树剖裸题,[Usaco2009 Jan]安全路经Travel 的简化版 剖开最短路树,遍历每一条没在最短路树上的边. 这种情况下,有且仅有u到v路径上,出来lca之外的点能够通过这条边到达,并 ...
随机推荐
- iOS-贝塞尔连续曲线
一个曲线 UIColor *color = [UIColor redColor]; [color set]; UIBezierPath *path = [UIBezierPath bezierPath ...
- vue-cli项目配置文件分析
最近在vue-cli生成的webpack模板项目的基础上开发了一些项目,开发过程中遇到很多坑,并且需要改动build和config里面一些相关的配置,查阅,学习,总结,分享. 一.配置文件结构 本文主 ...
- python2 里边自定义线程池
#!/usr/bin/env python # -*- coding:utf-8 -*- import Queue import threading class ThreadPool(object): ...
- How to resize or create a thumbnail image from file stream on UWP
最近在搞Ocr相关的windows universal app, 用到了一些图像处理相关的知识. 涉及到了BitmapDecoder/BitmapEncoder/IRandomAccessStream ...
- php -- 获取函数参数
----- 015-parameter.php ----- <!DOCTYPE html> <html> <head> <meta http-equiv=&q ...
- C#基础篇三流程控制2
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace P01R ...
- [Java初探04]__字符串(String类)相关
前言 接下来将暂时将重心偏移向实际操作,不在将大量时间花费在详细的知识点整理上,将会简略知识总结笔记的记录,加强实际练习的时间,实例练习篇也不再同步进行,我会将部分我觉得重要的源码更新在每节知识点后面 ...
- 接口测试学习笔记(Jmeter)
常见接口协议: 1.http 超文本传输协议 2.https 安全超文本传输协议 3.ftp 文件传输协议 4.tcp 网络控制协议 5.IP 互联网协议 6.udp 用户数据协议 -- HTTP协议 ...
- js便签笔记(5)——Dean Edwards大牛的跨浏览器AddEvent()设计(不知道是不是jQuery事件系统的原型)
1. 前言: 在看Aaron的jquery源码解读时候,看到事件系统那块,作者提到了Dean Edwards的添加事件的设计,于是就点进去看了看.首先让我吃惊的是,代码非常少,寥寥几十行,非常简单.于 ...
- 对CAP原理的理解
对CAP原理的理解 CAP原理按照定义,指的是C(Consistency)一致性,A(Availability)可用性,P(Partition tolerance)分区容错性在一个完整的计算机系统中三 ...