题目大意:

给定一个\(n\)的点的图。求\(s\)到所有点的最短路

边的给定方式有三种:

  • \(u \to v\)
  • \(u \to [l,r]\)
  • \([l,r] \to v\)

    设\(q\)为给定边的次数,有\(n,q \leq 10^5\)

题解

类比于线段树优化网络流建图

写一个线段树优化最短路建图即可。

#include <queue>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
#define rg register int
#define rep(i,a,b) for(rg i=(a);i<=(b);++i)
#define per(i,a,b) for(rg i=(a);i>=(b);--i)
const int maxn = 100010;
struct Edge{
int to,dis;
Edge(){}
Edge(const int &a,const int &b){
to = a;dis = b;
}
};
vector<Edge>ve[maxn*10];
inline void add(int u,int v,int d){
ve[u].push_back(Edge(v,d));
}
int T1[maxn<<2],T2[maxn<<2],nodecnt;
void build1(int rt,int l,int r){
T1[rt] = ++ nodecnt;
if(l == r){
add(l,T1[rt],0);
return ;
}
int mid = l+r >> 1;
build1(rt<<1,l,mid);
build1(rt<<1|1,mid+1,r);
add(T1[rt<<1],T1[rt],0);
add(T1[rt<<1|1],T1[rt],0);
}
void build2(int rt,int l,int r){
T2[rt] = ++ nodecnt;
if(l == r){
add(T2[rt],l,0);
return ;
}
int mid = l+r >> 1;
build2(rt<<1,l,mid);
build2(rt<<1|1,mid+1,r);
add(T2[rt],T2[rt<<1],0);
add(T2[rt],T2[rt<<1|1],0);
} int p,val;
void query1(int rt,int l,int r,int L,int R){
if(L <= l && r <= R){
add(T1[rt],p,val);
return ;
}
int mid = l+r >> 1;
if(L <= mid) query1(rt<<1,l,mid,L,R);
if(R > mid) query1(rt<<1|1,mid+1,r,L,R);
}
void query2(int rt,int l,int r,int L,int R){
if(L <= l && r <= R){
add(p,T2[rt],val);
return ;
}
int mid = l+r >> 1;
if(L <= mid) query2(rt<<1,l,mid,L,R);
if(R > mid) query2(rt<<1|1,mid+1,r,L,R);
}
ll dis[maxn*10];bool inq[maxn*10];
void spfa(int s){
memset(dis,0x3f,sizeof dis);
dis[s] = 0;inq[s] = true;
queue<int>q;q.push(s);
while(!q.empty()){
int u = q.front();q.pop();
for(vector<Edge>::iterator it = ve[u].begin();it != ve[u].end();++ it){
if(dis[it->to] > dis[u] + it->dis){
dis[it->to] = dis[u] + it->dis;
if(!inq[it->to]){
inq[it->to] = true;
q.push(it->to);
}
}
}inq[u] = false;
}
}
int main(){
int n,q,s;read(n);read(q);read(s);
int t,u,v,l,r;
nodecnt = n;
build1(1,1,n);build2(1,1,n);
while(q--){
read(t);
if(t == 1){
read(u);read(v);read(val);
add(u,v,val);
}else if(t == 2){
read(p);read(l);read(r);read(val);
query2(1,1,n,l,r);
}else if(t == 3){
read(p);read(l);read(r);read(val);
query1(1,1,n,l,r);
}
}
spfa(s);
rep(i,1,n){
if(dis[i] != dis[0]) printf("%lld",dis[i]);
else printf("%d",-1);
if(i != n) putchar(' ');
else putchar('\n');
}
return 0;
}

Codeforces 786B. Legacy 线段树+spfa的更多相关文章

  1. Codeforces.786B.Legacy(线段树优化建图 最短路Dijkstra)

    题目链接 \(Description\) 有\(n\)个点.你有\(Q\)种项目可以选择(边都是有向边,每次给定\(t,u,v/lr,w\)): t==1,建一条\(u\to v\)的边,花费\(w\ ...

  2. CodeForces - 786B Legacy (线段树+DIjkstra+思维)

    题意:给N个点和Q条选项,有三种类型的选项:1.从u到v花费w修建一条路:2.从u到下标区间为[L,R]的点花费w修建一条路; 3.从下标区间为[L,R]的点到u花费w修建一条路. 然后求起点s到其余 ...

  3. Codeforces 787D. Legacy 线段树建模+最短路

    D. Legacy time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...

  4. codeforces 787D - Legacy 线段树优化建图,最短路

    题意: 有n个点,q个询问, 每次询问有一种操作. 操作1:u→[l,r](即u到l,l+1,l+2,...,r距离均为w)的距离为w: 操作2:[l,r]→u的距离为w 操作3:u到v的距离为w 最 ...

  5. Codeforces 787D Legacy 线段树 最短路

    题意: 有\(n(1 \leq n \leq 10^5)\)个点,\(q(1 \leq q \leq 10^5)\)条路和起点\(s\) 路有三种类型: 从点\(v\)到点\(u\)需要花费\(w\) ...

  6. 786B - Legacy(线段树 + 最短路)线段树优化建图

    题意: 就是给定一张n nn个点的图,求源点s ss到每个点的单源最短路.这张图共有q组边,连边方式有3种: a→b ,边权为w的单向边:a→[l,r] ,即a到连续区间[l,r]中的每一个点都有一条 ...

  7. CodeForces 786B Legacy(线段树优化建图+最短路)

    [题目链接] http://codeforces.com/problemset/problem/786/B [题目大意] 给出一些星球,现在有一些传送枪,可以从一个星球到另一个星球, 从一个星球到另一 ...

  8. Codeforces 786B Legacy(线段树优化建图)

    题目链接  Legacy 首先对于输入的$n$,建立一棵线段树. 显然线段树有大概$2n$个结点,每个节点对应一段区间 我们把这$2n$个结点加入我们的无向图中,一起跑最短路. 具体连边方案: 我们把 ...

  9. CF786B Legacy 线段树优化建图 + spfa

    CodeForces 786B Rick和他的同事们做出了一种新的带放射性的婴儿食品(???根据图片和原文的确如此...),与此同时很多坏人正追赶着他们.因此Rick想在坏人们捉到他之前把他的遗产留给 ...

随机推荐

  1. dict字典常用方法总结,数据解构(解包)

    dict {'name':'holle'}字典存储大量关联型数据,可迭代的,最多只有200个键.查询数据速度非常快,符合二分查找(有100个数比如找75会先找到50然后判断,所以2^7次方7次即可找到 ...

  2. 前端 JavaScript&Dom

    JavaScript是一种属于网络的脚本语言,已经被广泛用于Web应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果.通常JavaScript脚本是通过嵌入在HTML中来实现 ...

  3. json教程系列(4)-optXXX方法的使用

    在JSONObject获取value有多种方法,如果key不存在的话,这些方法无一例外的都会抛出异常.如果在线环境抛出异常,就会使出现error页面,影响用户体验,针对这种情况最好是使用optXXX方 ...

  4. Using中return对象

    class Program { static void Main(string[] args) { Test test = new Test(); var a = test.CreateA(); te ...

  5. linux性能调分析及调优

    转:https://blog.csdn.net/luokehua789789/article/details/53007456 Linux 性能分析以及调优介绍 写在前面:计算机要解决的基本问题之一是 ...

  6. 如何理解Java程序使用Unicode字符集编写

    Java采用UTF-16编码作为内码,也就是说在JVM内部,文本是用16位码元序列表示的,常用的文本就是字符(char)和字符串(String)字面常量的内容.注:UTF-16是Unicode字符集的 ...

  7. Python编程-多线程

    一.python并发编程之多线程 1.threading模块 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性,因而不再详细介绍 1.1 开启线程的 ...

  8. PHP中的常见魔术方法功能作用及用法实例

    概述 在面向对象编程中,PHP提供了一系列的魔术方法,这些魔术方法为编程提供了很多便利.PHP中的魔术方法通常以__(两个下划线)开始,并且不需要显示的调用而是由某种特定的条件出发. 开始之前 在总结 ...

  9. Pandas基础用法-数据处理【全】-转

    完整资料:[数据挖掘入门介绍] (https://github.com/YouChouNoBB/data-mining-introduction) # coding=utf-8 # @author: ...

  10. Web项目java.lang.OutOfMemoryError: PermGen space异常解决

    接手一个新的Web项目,编译运行(Tomcat版本为7),运行的时候报出了java.lang.OutOfMemoryError: PermGen space的异常,搜了一下这样解释:   PermGe ...