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之外的点能够通过这条边到达,并 ...
随机推荐
- pycharm光标变成黑框,恢复成竖线
pycharm光标变成黑框,如下图所示 解决办法: 按外接键盘上的Insert键,即可恢复.
- MySQL 中文字符集排序
SELECT 字段名 FROM 表 ORDER BY CONVERT(字段名 USING gbk) ASC;
- JavaScript getter和setter
对象的属性是由属性名name,值key,和其他特性(可读写性 writable,可枚举性enumerable,可配置性configurable)组成的.从ES5开发,提供了getter和setter ...
- Spring Integration Zip不安全解压(CVE-2018-1261)漏洞复现
不敢说分析,还是太菜了,多学习. 文章来源: 猎户安全实验室 存在漏洞的源码下载地址:https://github.com/spring-projects/spring-integration-ext ...
- [LeetCode]138复制带随机指针的链表
题目描述: 给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点. 要求返回这个链表的深度拷贝. 思路: 先遍历链表,将每个节点对应的随机指针指向的对象利用Hash ...
- SQLAlchemy的ORM
表关系: 表之间的关系存在三种:一对一.一对多.多对多.而SQLAlchemy中的ORM也可以模拟这三种关系.因为一对一其实在SQLAlchemy中底层是通过一对多的方式模拟的,所以先来看下一对多的关 ...
- MySQL高可用架构-MMM安装教程
安装指南: 一.架构以及服务器信息 基本安装包含至少2个数据库服务器和1个监视服务器.本例中使用2个监视服务器和5个数据库服务器(服务器系统为CentOS 7) 用途 IP 主机名 Server-id ...
- WebForm - cookie赋值乱码问题
cookie的值为中文时候,取cookie的值会出现乱码 解决办法:存取cookie时候先解码和编码 存cookie,进行编码: cookie.Value = HttpUtility.UrlEncod ...
- 08-01 java 帮助文档的制作和使用,使用jdk提供的帮助文档
01_帮助文档的制作和使用 制作说明书的流程 如何制作一个说明书呢? A:写一个工具类 B:对这个类加入文档注释 怎么加呢? 加些什么东西呢? C:用工具解析文档注释 javadoc工具 D:格式 j ...
- PHP:session无法使用
今天在将一套程序放到其他服务器上执行的时候,发现后台的登录验证码不管输入正确与否,总是显示: 验证码输入有误 接着就开始debug了. 因为正确的验证码结果已经经过加密之后保存在了session中,所 ...