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之外的点能够通过这条边到达,并 ...
随机推荐
- 《Python黑帽子:黑客与渗透测试编程之道》 自动化攻击取证
工具安装: 下载源码:https://code.google.com/archive/p/volatility/downloads 工具配置: 获取内存镜像:https://www.downloadc ...
- Dubbo实现原理之基于SPI思想实现Dubbo内核
dubbo中SPI接口的定义如下: @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) public ...
- 【Junit4】:要点随笔
1. 引入Junit4的Maven依赖 <dependencies> <dependency> <groupId>junit</groupId> < ...
- eclipse maven打war包
在eclipse中找到pom.xml文件右键 选择debug as 再选择Maven install运行后 按路径找到生成的war包 推荐https://www.cnblogs.com/qlqwjy/ ...
- ubuntu安转QTcreator出现The default mkspec symlink is broken
QT Creator安装:https://blog.csdn.net/arackethis/article/details/42326967 QT SDK安装:https://blog.csdn.ne ...
- Flexbox指南
Flexbox布局(Flexible Box)模块旨在提供一个更加有效的方式制定.调整和分布一个容器里的项目布局,即使他们的大小是未知或者是动态的.(这里我们称为Flex). Flex布局主要思想是让 ...
- ES6基础教程一 学习笔记
一.变量的声明 1.var 声明全局变量 在ES6中var用来声明全局变量. 2.let 声明局部变量 3.const 声明常量 二.变量的解构赋值 //1.数组赋值 let [a,b,c]=[1,2 ...
- 安装python-devel开发包
1.概述 有时在安装某些软件的时候,会报错: Error: must have python development packages -devel, python2.-devel, python2. ...
- JavaScript中十种一步拷贝数组的方法
JavaScript中我们经常会遇到拷贝数组的场景,但是都有哪些方式能够来实现呢,我们不妨来梳理一下. 1.扩展运算符(浅拷贝) 自从ES6出现以来,这已经成为最流行的方法.它是一个很简单的语法,但是 ...
- 29-hadoop-使用phtonenix工具&分页&数据导入
因为rowkey一般有业务逻辑, 所以不可以直接使用rowkey进行分页, startkey, endkey 想要使用SQL语句对Hbase进行查询,需要使用Apache的开源框架Phoenix. 安 ...