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

然后求起点s到其余点的最短路。

如果直接暴力建图,建图本身就会超时。对于区间上的操作,考虑用线段树解决。线段树上的结点本身就能代表一段区间的点,所以在建图时,用树上的结点充当中间结点。(有点网络流的思想?)

因为要建一张有向图,所以图的点到树上结点要连边,反之亦然;但是在一棵线段树上双向连边就不能对所有的点跑最短路了(因为图中的点可能会在树上找到权值为0的回路回到自己)。

所以再建一棵线段树去表示反向连边的关系。

对每个树上结点从N+1开始编号,将其与之维护的区间中的点连一条花费为0的边。每次更新就是用把给定区间[L,R]囊括的所有树上结点与给定的u连边。操作2和操作3分别对应两棵线段树的结点。

#include<bits/stdc++.h>
#define lson rt<<1
#define rson rt<<1|1
#define Lson l,m,lson
#define Rson m+1,r,rson
using namespace std;
typedef long long LL;
const int maxn = 4e5+5;
const LL INF = (1LL)<<60;
struct Edge{int to,next;LL w;
}edges[maxn<<4];
int head[maxn<<4],tot;
int ID[maxn<<2],rID[maxn<<2];
int id;void init(int N)
{memset(head,-1,sizeof(head));tot=0;id = N;
}void AddEdge(int u,int v,LL w){edges[tot] = (Edge){v,head[u],w};head[u] = tot++;
}void build(int l,int r,int rt,bool flag)
{if(!flag) ID[rt] = ++id;else rID[rt] = ++id;if(!flag) {for(int i=l;i<=r;++i) AddEdge(ID[rt],i,0);}else {for(int i=l;i<=r;++i) AddEdge(i,rID[rt],0);}if(l==r) return;int m = (l+r)>>1;build(Lson,flag);build(Rson,flag);
}void update(int L,int R,LL w,int u,int l,int r,int rt,bool flag)
{if(L<=l && R>=r){if(!flag)AddEdge(u,ID[rt],w);else AddEdge(rID[rt],u,w);return;}int m =(l+r)>>1;if(L<=m) update(L,R,w,u,Lson,flag);if(R>m) update(L,R,w,u,Rson,flag);
}LL d[maxn<<4];
bool used[maxn<<4];
struct HeapNode{LL d;int u;bool operator <(const HeapNode & rhs) const {return d > rhs.d;}
};
void dijkstra(int s){   memset(used,0,sizeof(used));priority_queue<HeapNode> Q;for(int i=0;i<=id;++i)    d[i]=INF;d[s]=0;Q.push((HeapNode){0,s});while(!Q.empty()){HeapNode x =Q.top();Q.pop();int u =x.u;if(used[u])  continue;used[u]= true;for(int i=head[u];~i;i=edges[i].next){Edge & e = edges[i];if(d[e.to] > d[u] + e.w){d[e.to] = d[u] +e.w;Q.push((HeapNode){d[e.to],e.to});}}}}
int main()
{#ifndef ONLINE_JUDGEfreopen("in.txt","r",stdin);freopen("out.txt","w",stdout);#endifint T,N,M,q,s,u,v,op,L,R;LL w;while(scanf("%d%d%d",&N,&q,&s)==3){init(N);build(1,N,1,0);build(1,N,1,1);while(q--){scanf("%d",&op);if(op==1){scanf("%d%d%lld",&u,&v,&w);AddEdge(u,v,w);}else if(op==2){scanf("%d%d%d%lld",&u,&L,&R,&w);update(L,R,w,u,1,N,1,0);}else{scanf("%d%d%d%lld",&u,&L,&R,&w);update(L,R,w,u,1,N,1,1);}}dijkstra(s);for(int i=1;i<=N;++i)printf("%lld%c",d[i]==INF?-1:d[i],i==N?'\n':' ');}return 0;
}

转载于:https://www.cnblogs.com/xiuwenli/p/9437712.html

CodeForces - 786B Legacy (线段树+DIjkstra+思维)相关推荐

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

    Codeforces 786B Legacy (线段树优化建图) 题意:\(n\)个点,有\(3\)种连边操作:1.将\(u\)指向\(v\):2.将\(v\)指向编号在区间\([l,r]\)的点:3 ...

  2. CodeForces - 787D - Legacy(线段树优化建图+最短路)

    题目链接:点击查看 题目大意:给出 nnn 个点和 mmm 条边,现在需要求从 ststst 开始到所有点的最短路是多少,mmm 条边的给出方式如下: 1uvw1 \ u \ v \ w1 u v w ...

  3. CodeForces - 1326E Bombs(线段树+思维)

    题目链接:点击查看 题目大意:给出一个 n 的排列记为 p[ i ] ,现在有一个初始时为空的集合A,对于每个 i 遍历 1 ~ n ,每次的操作如下: 向集合中添加 p[ i ] 如果位置 i 有炸 ...

  4. Sereja and Brackets CodeForces - 380C (线段树+分治思路)

    Sereja and Brackets 题目链接: CodeForces - 380C Sereja has a bracket sequence s1, s2, ..., *s**n, or, in ...

  5. 「JOISC 2020 Day4」治疗计划(线段树+dijkstra最短路)

    「JOISC 2020 Day4」治疗计划 description solution 设dpi:1−Ridp_i:1-R_idpi​:1−Ri​ 都能被救治成功的最小花费 两个治疗方案[Li,Ri], ...

  6. CodeForces - 487B Strip(线段树+dp+二分)

    题目链接:点击查看 题目大意:给出一个长度为 n 的序列,现在要求分成尽可能少的子段,且每个子段需要满足: 最大值与最小值的差值小于等于 s 子段长度大于等于 l 题目分析:dp[ i ] 代表的是前 ...

  7. CodeForces - 1354D Multiset(线段树/二分)

    题目链接:点击查看 题目大意:规定在一个 multiset 中初始时有 n 个元素,随后有 m 次操作,每次操作给出一个 num: num > 0 时:向 multiset 中添加 num nu ...

  8. 洛谷T44252 线索_分治线段树_思维题

    分治线段树,其实就是将标记永久化,到最后再统一下传所有标记. 至于先后顺序,可以给每个节点开一个时间戳. 一般地,分治线段树用于离线,只查询一次答案的题目. 本题中,标记要被下传 222 次. Cod ...

  9. New Year and Old Subsequence CodeForces - 750E(线段树+矩阵dp)2019南昌icpc网络赛Hello 2019

    A string t is called nice if a string "2017" occurs in t as a subsequence but a string &qu ...

  10. 【HDU - 5489】Removed Interval(离散化,权值线段树,思维,最长上升子序列)

    题干: Given a sequence of numbers A=a1,a2,-,aNA=a1,a2,-,aN, a subsequence b1,b2,-,bkb1,b2,-,bk of AA i ...

最新文章

  1. QIIME 2用户文档. 15进行纵向和成对样本比较q2-longitudinal(2018.11)
  2. 金升阳5V开关电源LM25-23B05
  3. 肤色检测算法 - 基于二次多项式混合模型的肤色检测
  4. 概率统计:第一章 概率论的基本概念
  5. 什么?还有可以攻击telegram和其他APP的恶意软件
  6. 在Windows服务器上开启SNMP代理程序
  7. Codeforces 1159A A pile of stones
  8. 【学术相关】你只看到了200万年薪的招聘,看不到被困校园的几十万博士
  9. 计算机永远无法处理日语所具有的暧昧性,计算机永远无法处理日语所具有的暧昧性。( )...
  10. 提交第一个spark作业到集群运行
  11. 云小课 | MRS和自建Hadoop相比,有哪些优势?
  12. 【Java小项目】简单的天气预报
  13. 题目399-整除个数(满满的套路)
  14. html常用语言代码大全,常用的html代码大全
  15. 荣耀magicbook笔记本BIOS设置
  16. 20年在线考试计算机应用基础,20年春福师《计算机应用基础》在线作业一【参考答案】...
  17. css各种角度的三角形
  18. python机械臂仿真_机械臂 python
  19. vant框架cdn使用方式的简短案例
  20. 论文阅读——TR-GAN: Topology Ranking GAN with Triplet Loss for Retinal Artery/Vein Classification

热门文章

  1. 拓端tecdat|R使用LASSO回归预测股票收益
  2. 拓端tecdat|R语言Bass模型进行销售预测
  3. 成功解决./nvidia-installer: invalid option: “‐‐no‐opengl‐files“ ERROR: Invalid commandline, please run `
  4. 【RBM】代码学习--DeepLearningToolBox
  5. cvScale 深度转换 线性变换
  6. 华为荣耀手机指令代码大全_2020.10月《各价位华为、荣耀手机推荐》
  7. oracle中常用的方法,oracle常用方法
  8. python安装换源_Python切换pip安装源的方法详解
  9. python是如何进行内存管理的_Python是如何进行内存管理的?
  10. ❤️区块链Hyperledger Fabric 老版本 1.1.0 快速部署安装 教程合集❤️