CodeForces - 786BLegacy——线段树建图+最短路
【题目描述】
CodeForces - 786BLegacy
【题目分析】
题目大概意思就是有三种操作:
- 从某个点到另一个点
- 从某个点到另一个区间
- 从某个区间到另一个点
然后询问从其中一个点到其他所有点的距离——这很显然是一个求单源最短路径的。我们简单的想法显然是建一个图,每次操作就进行暴力连边,反正也没有修改。可是复杂度不允许。
我们再观察一下操作:对区间的操作,这让我们不由得想起了线段树,毕竟线段树可是区间神器,可是就算用了线段树,我们能做些什么呢?
线段树是保存区间信息的数据结构,我们对于从点到区间的关系,不妨修改为从点到线段树节点的关系,然后再使线段树节点和他们的叶子节点之间本来就带有一条路径,那么从一个点到另一个区间的关系就这样被简化为从一个点到几个点的关系,可以有效降低复杂度。
具体做法就是在建树的过程中就让每个线段树节点和他们的叶子节点之间含有一条权值为0的有向边。
之所以是有向边是因为从点到区间的关系有两种,我们得建立两种线段树,分别是从父节点指向叶子节点和从叶子结点指向根节点,对应的是从点到区间和从区间到点的关系。而且两个线段树的叶子节点,也就是最下面的节点指向的都是原来区间的节点,这样就在原来的区间上建立了从点到区间再从区间到点的关系。详细情况可以看一下另一位大佬博主的图
这个图是进行了三个操作:
1 2 3 3 节点2到节点3有一条权值为3的边(蓝色)
2 1 2 4 2 节点1到区间[2,4]有权值为2的边(黄色)
3 4 1 3 1 区间[1,3]到节点4有权值为1的边(红色)
再在这张图上跑最短路(因为有0边,最好还是用SPFA)
【AC代码】
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#include<climits>
#include<cstdlib>
#include<cmath>using namespace std;typedef long long ll;const int MAXN=100005;
const ll INF=0x3f3f3f3f3f3f3f3f;
int head[MAXN<<2],ls[MAXN<<2],rs[MAXN<<2];
int root1,root2,tot,cnt;
struct edge
{int v,w,next;
}edge[MAXN*20];
ll dis[MAXN<<2];
queue<int> q;inline void AddEdge(int u,int v,int w)
{edge[++tot].v=v; edge[tot].w=w; edge[tot].next=head[u]; head[u]=tot;
}void build1(int &k,int l,int r)
{if(l==r){k=l; return;}k=++cnt;int mid=(l+r)>>1;build1(ls[k],l,mid); build1(rs[k],mid+1,r);AddEdge(k,ls[k],0); AddEdge(k,rs[k],0);
}void build2(int &k,int l,int r)
{if(l==r){k=l; return;}k=++cnt;int mid=(l+r)>>1;build2(ls[k],l,mid); build2(rs[k],mid+1,r);AddEdge(ls[k],k,0); AddEdge(rs[k],k,0);
}void update1(int k,int l,int r,int x,int L,int R,int w)
{if(l>=L && r<=R){AddEdge(x,k,w);return;}int mid=(l+r)>>1;if(L<=mid) update1(ls[k],l,mid,x,L,R,w);if(R>mid) update1(rs[k],mid+1,r,x,L,R,w);
}void update2(int k,int l,int r,int x,int L,int R,int w)
{if(l>=L && r<=R){AddEdge(k,x,w);return;}int mid=(l+r)>>1;if(L<=mid) update2(ls[k],l,mid,x,L,R,w);if(R>mid) update2(rs[k],mid+1,r,x,L,R,w);
}void SPFA(int s)
{memset(dis,0x3f,sizeof(dis));dis[s]=0; q.push(s);while(!q.empty()){int u=q.front(); q.pop();for(int i=head[u];i;i=edge[i].next){int v=edge[i].v,w=edge[i].w;if (dis[u]+w<dis[v]) dis[v]=dis[u]+w,q.push(v);}}
}int main()
{int n,m,s;int cmd,l,r,v,w,u;scanf("%d%d%d",&n,&m,&s);cnt=n; tot=0;build1(root1,1,n); build2(root2,1,n);for(int i=0;i<m;i++){scanf("%d",&cmd);if(cmd==1){scanf("%d%d%d",&u,&v,&w);AddEdge(u,v,w);}else{scanf("%d%d%d%d",&v,&l,&r,&w);if(cmd==2)update1(root1,1,n,v,l,r,w);elseupdate2(root2,1,n,v,l,r,w);}}SPFA(s);for(int i=1;i<=n;i++){cout<<(dis[i]<INF?dis[i]:-1)<<" ";}return 0;
}
CodeForces - 786BLegacy——线段树建图+最短路相关推荐
- hdu 5420 Victor and Proposition(强连通+线段树建图)
题意:给出一棵树,每个点都给一个x,d,代表它和x这个点以及以下深度差小于d的点都有一条有向边,求互相可达的u,v对数. 做法:可以很容易发觉如果我们把点连好然后直接找强连通分量,然后答案就是每个强连 ...
- hdu 5420 Victor and Proposition 线段树建图+强连通分量
题意: http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=620&pid=1003 题目求有多少对互为充要 ...
- CodeForces - 787D - Legacy(线段树优化建图+最短路)
题目链接:点击查看 题目大意:给出 nnn 个点和 mmm 条边,现在需要求从 ststst 开始到所有点的最短路是多少,mmm 条边的给出方式如下: 1uvw1 \ u \ v \ w1 u v w ...
- CodeForces---787D:Legacy【线段树优化建图+最短路】
题目: 戳这里啊~~~ 题意: 给你三种操作:(1)点到点建边:(2)点到区间建边:(3)区间到点建边:最后求起点到其他点的最短距离 分析: 最短距离无非建边跑Dijkstra即可,考虑如何对区间建边 ...
- Codeforces 1140F 线段树 分治 并查集
题意及思路:https://blog.csdn.net/u013534123/article/details/89010251 之前cf有一个和这个相似的题,不过那个题只有合并操作,没有删除操作,直接 ...
- Sum of Medians CodeForces - 85D(线段树+离散化)
Sum of Medians 题目链接:CodeForces - 85D 题意:对于一个集合set(有序的)有三个操作(集合是有序的,下标由1开始): 一:add x:在集合中加入x; 二:del ...
- ZONe Sneaking 优化建图 + 最短路
传送门 题目描述 分析 因为每次移动的权值不一样,所以肯定不能用BFSBFSBFS求解,不然就是类似于spfaspfaspfa的写法,容易被卡,所以我们可以去暴力建图然后跑堆优化的dij 怎么建图呢, ...
- CodeForces 444C 线段树
想分块想了很久一点思路都没有,结果一看都是写的线段树= = ...完全忘记了还有线段树这种操作 题意:给一个数组,一种操作是改变l到r为c,还有一种操作是查询l到r的总和差 线段树记得+lazy标记 ...
- Codeforces 438D 线段树 解题报告
D. The Child and Sequence At the children's day, the child came to Picks's house, and messed his hou ...
最新文章
- 在人脸识别的时候,一定要穿上衣服啊!
- 53 Paramiko的使用
- 20189211 《网络攻防》第五周作业
- 【Demo】配置重试和超时策略
- 计算机专业网站的开题ppt,.计算机专业开题报告.ppt
- Java Lambda 表达式讲解
- 信息学奥赛一本通(1315:【例4.5】集合的划分)
- 设备树语法和多任务处理
- pg库sharelock_PostgreSQL 行锁解读
- 还在家隔离呢?没事写写这些程序吧!
- matlab曲线拟合的应用,MATLAB软件在曲线拟合中的应用
- phpzend框架_PHP框架Zend
- 2015 2020 r4烧录卡 区别_每分时长来看2010年与2015年与2020年澳网男单决赛的区别...
- 【typecho插件】typecho邮箱插件LoveXXzhoudedi祝福邮箱typecho插件、小周
- Eclipse中出现无法找到Maven包Active Maven Profiles (comma separated)
- PLETL的主谓宾 定状补模式 命令 已经设计更新并执行成功如图 中节点 的m_ID 输出已经出现 ,已经开源
- Scala中TypeTags和Manifests的用法
- codeforces 85D. Sum of Medians(线段树or分块)
- Windows7桌面变更语言简易切换不重装
- esp32-s2 wifi
热门文章
- 201771010120 苏浪浪 《面向对象程序设计(java)》第二周学习总结
- CentOS Vi编辑器
- Ubuntu+vscode打不开
- [python]-数据科学库Numpy学习
- nginx 配置优化详解
- 解析css之position
- java 文件解析异常_java中异常的解析
- 三菱st语言编程实例_LD、FBD、IL、ST、SFC、CFC六种编程语言的特点
- pcb成型板aoi检测_基于AOI技术的PCB常见质量缺陷检测
- vs mysql iss_MySQL5.7与8.0的连接问题(vs2015\2017)