CF786B Legacy(线段树优化建图)

Posted xu-daxia

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF786B 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;求起点到其他点的最短距离,到达不了输出-1。

题解

线段树骚操作,线段树优化建图。

其实提到可以这么操作后,实现还是很好想的。

建两颗线段树,一颗连进边,一颗连出边。

技术分享图片
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<algorithm>
  6 #include<map>
  7 #include<queue>
  8 #include<vector>
  9 using namespace std;
 10 typedef long long ll;
 11 const int MAXN=5e6+100,inf=0x3f3f3f3f,MOD=1e9+7;
 12 const ll INF=1e17+10;
 13 struct node
 14 {
 15     int to;
 16     ll w;
 17     int next;
 18 } edge[MAXN];
 19 int cou,head[MAXN];
 20 int Max;
 21 int vis[MAXN];
 22 ll ans[MAXN];
 23 void init()
 24 {
 25     cou=0;
 26     Max=0;
 27     memset(vis,0,sizeof(vis));
 28     memset(head,-1,sizeof(head));
 29 }
 30 void add(int u,int v,ll w)
 31 {
 32     cou++;
 33     edge[cou].to=v;
 34     edge[cou].w=w;
 35     edge[cou].next=head[u];
 36     head[u]=cou;
 37     ///cout<<u<<" "<<v<<" "<<w<<endl;
 38 }
 39 void build(int l,int r,int pos,int flag,int t)
 40 {
 41     if(t==2) Max=max(Max,pos+flag);
 42     if(l==r)
 43     {
 44         if(t==2) add(pos+flag,l,0LL);
 45         else add(l,pos+flag,0LL);
 46         return;
 47     }
 48     if(t==2)
 49     {
 50         add(pos+flag,(pos<<1)+flag,0LL);
 51         add(pos+flag,(pos<<1|1)+flag,0LL);
 52     }
 53     else
 54     {
 55         add((pos<<1)+flag,pos+flag,0LL);
 56         add((pos<<1|1)+flag,pos+flag,0LL);
 57     }
 58     int mid=(l+r)>>1;
 59     build(l,mid,pos<<1,flag,t);
 60     build(mid+1,r,pos<<1|1,flag,t);
 61 }
 62 void update(int L,int R,ll w,int l,int r,int pos,int flag,int u,int t)
 63 {
 64     if(L<=l&&r<=R)
 65     {
 66         if(t==2) add(u,pos+flag,w);
 67         else add(pos+flag,u,w);
 68         return;
 69     }
 70     int mid=(l+r)>>1;
 71     if(L<=mid) update(L,R,w,l,mid,pos<<1,flag,u,t);
 72     if(R>mid) update(L,R,w,mid+1,r,pos<<1|1,flag,u,t);
 73 }
 74 struct mmp
 75 {
 76     int s;
 77     ll dis;
 78     mmp() {}
 79     mmp(ll ss,ll d)
 80     {
 81         s=ss,dis=d;
 82     }
 83     bool operator <(const  mmp &x)const
 84     {
 85         return dis>x.dis;
 86     }
 87 };
 88 priority_queue<mmp>q;
 89 void dij(int s)
 90 {
 91     ans[s]=0LL;
 92     q.push(mmp(s,0LL));
 93     while(!q.empty())
 94     {
 95         mmp now=q.top();
 96         q.pop();
 97         int u=now.s;
 98         if(vis[u]) continue;
 99         vis[u]=1;
100         for(int i = head[u]; i!=-1; i=edge[i].next)
101         {
102             int v=edge[i].to;
103             ll w=edge[i].w;
104             if(ans[v]>now.dis+w)
105             {
106                 ///cout<<u<<" "<<v<<" "<<ans[u]+w<<endl;
107                 q.push(mmp(v,now.dis+w));
108                 ans[v]=now.dis+w;
109             }
110         }
111     }
112 }
113 int main()
114 {
115     int n,q,s;
116     scanf("%d%d%d",&n,&q,&s);
117     init();
118     build(1,n,1,n+1,2);
119     build(1,n,1,Max+1,3);
120     for(int i=1; i<=q; i++)
121     {
122         int t;
123         scanf("%d",&t);
124         if(t==1)
125         {
126             int u,v;
127             ll w;
128             scanf("%d%d%lld",&u,&v,&w);
129             add(u,v,w);
130         }
131         else
132         {
133             int u,l,r;
134             ll w;
135             scanf("%d%d%d%lld",&u,&l,&r,&w);
136             if(t==2) update(l,r,w,1,n,1,n+1,u,t);
137             else update(l,r,w,1,n,1,Max+1,u,t);
138         }
139     }
140     for(int i=0;i<MAXN;i++) ans[i]=INF;
141     dij(s);
142     for(int i=1; i<=n; i++)
143     {
144         if(ans[i]>=INF) cout<<"-1 ";
145         else cout<<ans[i]<<" ";
146     }
147     cout<<endl;
148     return 0;
149 }
View Code

 

以上是关于CF786B Legacy(线段树优化建图)的主要内容,如果未能解决你的问题,请参考以下文章

CF786B Legacy(线段树优化建图)

CF786B Legacy(线段树优化建图)

CF786B Legacy(线段树优化建图+最短路)

CF786B Legacy

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

codeforces786B Legacy 线段树优化建图