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之外的点能够通过这条边到达,并 ...
随机推荐
- Linux系统软件包的管理(4)
虽然使用源码编译安装可以具有提高速度个性化的定制等优点,但对于 Linux发行商来说,则不容易管理软件包,毕竟不是每个人都会进行源码编译的,如果能够将软件预先在相同的硬体与系统上面编译好在发布的话,不 ...
- 社会地位即服务, Status as a Service (二): 社交网络的投资回报率 (ROI)
本文作者 Eugene Wei 是 Amazon 战略部门的第一位分析师,后来还担任过 Flipboard, Hulu, Oculus 的产品负责人. 原文标题是 Status as a Servic ...
- Redis 入门知识
Redis 的前世今生 Redis的诞生于2008年,由Salvatore Sanfilippo开发.最初作者在开发一个网站时,需要实现一个高性能的队列功能,在使用Mysql无果后,决定自己造一个轮子 ...
- Oracle修改日志归档模式、归档路径以及空间大小的相关测试
ORACLE 创建数据库的时候要不要开启日志归档? oracle数据库可以运行在2种模式下:归档模式(archivelog)和非归档模式(noarchivelog) .归档模式可以提高Oracle数据 ...
- (转)CentOS一键安装Nginx脚本
原文:https://www.xiaoz.me/archives/10301 https://blog.slogra.com/post-676.html-----centos7一键安装nginx脚本
- (转)IHS配置安全漏洞: 支持不推荐使用的 SSL 版本、在降级的旧加密上填充 Oracle、检测到 RC4 密码套件、支持弱 SSL 密码套件、 重构 RSA 导出键(又称为 FREAK)
原文:https://blog.csdn.net/lyd135364/article/details/52179426 都是由于ihs配置中支持不推荐使用的ssl版本和弱密码套件引起的. 只要在配置文 ...
- jenkins 通过shell启动tomcat会随着job完成而被自动关闭的解决方法
jenkins 通过shell启动tomcat会随着job完成而被自动关闭的解决方法 填入BUILD_ID=随便填什么 原理是:我不知道
- 02-05:springboot文件的上传
1.在static 下建立upload.html文件 <!DOCTYPE html> <html> <head> <meta charset="UT ...
- php获取 POST请求的数据
普通键值对的数据: $_POST[‘username’]; // 获取 username的信息: $_REQUEST; //则会获取 整个请求中的键值对,返回结果为数组: 如果是,流数据,则需要使用: ...
- Unity生成WebService代理类
普通的.net程序中,如果我们想引用webService,只需在项目中右键选择添加服务引用,然后在地址栏中输入Webservice地址,单击“转到”按钮,找到服务后再单击确定,Visual Studi ...