博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CF786B Legacy(线段树优化建图+最短路)
阅读量:5214 次
发布时间:2019-06-14

本文共 2697 字,大约阅读时间需要 8 分钟。

在qbxt某营集体做的

题解里以及外地OIer基本上都写两颗线段树的

而我们六安的OIer神TM思维一致——只用一颗线段树,类似于一维分层图的思想,第二层上与第一层相对应的结点的编号是第一层结点编号+NUM,而且貌似比分颗的思维正常一点,因为满足lson=k<<1,rson=k<<1|1,和一般的线段树相似度高。

至于为什么要分颗或分层,容易想明白树边(辅助边)必须是双向的(因为要用祖先结点的出入信息),但如果不分颗或分层的话求出来最短路不很明显是0了吗QwQ

所以分层的话父向子应是一层,子向父应在另一层,两层之间通过叶节点相连

另外关于叶结点的处理问题,YoOXiii和Pride205是把原图第i结点投影到树上第i+n结点(n为原图结点个数)

这个详见他们的代码(其实我也没仔细研究清楚他们的处理方法),这里不偷了(偷窃犯罪w),要看自己找

由于我和他们不坐一块,想思路时没有交流,所以我没有这样写,我是把第一层按照一般线段树的编号建,这样容易一点。然后把原图结点直接向叶子结点映射即可(开一个pos数组)(才知道szsz46也是这么写的,原来六安OIer的思维同步性不随空间改变QwQ)

然后......

上代码吧

#include
#include
#include
#include
#include
#define NUM 1000000#define maxn 100005<<5//这两个范围要调好 #define int long longusing namespace std;typedef long long ll;inline void input(ll &x){ ll ans=0,f=1; char c=getchar(); while(c>'9'||c<'0'){ if(c=='-')f=-1; c=getchar(); } while(c>='0'&&c<='9'){ ans=ans*10+c-48; c=getchar(); } x=ans*f;}inline void output(ll x){ if(x<0)x=-x,putchar('-'); if(x>9)output(x/10); putchar(x%10+48);}inline void writeln(ll x){ output(x); putchar('\n');}int n,m,s,head[maxn],c[maxn],pos[maxn],vis[maxn],dis[maxn],cnt;//pos:题中结点在树上的编号 struct edge{ int v,w,next;}e[maxn];struct node{ int dis,u; bool operator<(const node &x)const{return x.dis
>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); add(k<<1,k,0); add(k<<1|1,k,0); add(k+NUM,(k<<1)+NUM,0);//调了一个小时:加括号;在括号外加NUM而不是给k加NUM add(k+NUM,(k<<1|1)+NUM,0);}inline void add(int k,int l,int r,int xl,int xr,int from,int w,int opt){ if(xl<=l&&r<=xr){ if(opt==2)add(from,k+NUM,w); else if(opt==3)add(k,from,w); return; } int mid=(l+r)>>1; if(xl<=mid)add(k<<1,l,mid,xl,xr,from,w,opt); if(xr>=mid+1)add(k<<1|1,mid+1,r,xl,xr,from,w,opt);}priority_queue
q;inline void dijkstra(){ s=pos[s]; q.push((node){0,s}); dis[s]=0; while(!q.empty()){ int x=q.top().u; q.pop(); if(vis[x])continue; vis[x]=1; for(int i=head[x];i!=-1;i=e[i].next){ int y=e[i].v; if(!vis[y]&&dis[y]>dis[x]+e[i].w){ dis[y]=dis[x]+e[i].w; q.push((node){dis[y],y});//想不到吧,这一行打错使我调了半个小时 } } } s<<=1; if(s>=1)dijkstra();}signed main(){ memset(head,-1,sizeof(head)); memset(dis,127,sizeof(dis)); memset(vis,0,sizeof(vis)); input(n);input(m);input(s); build(1,1,n); for(int i=1;i<=m;i++){ int opt; input(opt); if(opt==1){ int u,v,w; input(u);input(v);input(w); add(pos[u],pos[v],w); } else if(opt==2){ int u,l,r,w; input(u);input(l);input(r);input(w); add(1,1,n,l,r,pos[u],w,opt); } else if(opt==3){ int u,l,r,w; input(u);input(l);input(r);input(w); add(1,1,n,l,r,pos[u],w,opt); } } dijkstra();// for(int i=1;i<=4*n;i++)cout<
<<' '<
<

转载于:https://www.cnblogs.com/Y15BeTa/p/11318060.html

你可能感兴趣的文章
js 封装获取元素的第一个元素
查看>>
iOS 获取Home键指纹验证
查看>>
Python-Mac 安装 PyQt4
查看>>
P2571 [SCOI2010]传送带
查看>>
哈希表1
查看>>
用Data Url (data:image/jpg;base64,)将小图片生成数据流形式
查看>>
实验2-2
查看>>
C#初识
查看>>
String,StringBuffer与StringBuilder的区别?? .
查看>>
JavaScript(三) 数据类型
查看>>
移动端rem布局屏幕适配插件(放js中便可使用)
查看>>
Docker
查看>>
bzoj2259 [Oibh]新型计算机
查看>>
对位与字节的深度认识
查看>>
C++编程基础二 16-习题4
查看>>
MongoDB遇到的疑似数据丢失的问题。不要用InsertMany!
查看>>
服务器被疑似挖矿程序植入107.174.47.156,发现以及解决过程(建议所有使用sonatype/nexus3镜像的用户清查一下)...
查看>>
类型“XXX”的控件“XXXX”必须放在具有 runat=server 的窗体标记内。
查看>>
JQuery 学习
查看>>
session token两种登陆方式
查看>>