zoukankan      html  css  js  c++  java
  • 线段树优化建图 || CF786B Legacy

    题面:786B - Legacy

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<queue>
      5 #define ll long long
      6 using namespace std;
      7 inline ll rd(){
      8     ll x=0,f=1;char c=getchar();
      9     while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
     10     while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
     11     return f*x;
     12 }
     13 const int maxn=(1e5)+50,maxq=maxn;
     14 const ll inf=1ll<<60;
     15 int N,S,Q,o,v,u,ql,qr,num_edge=0,edge_head[maxn*15];
     16 int tr[maxn*15][3],cnt;
     17 ll w,Dis[maxn*15];
     18 bool vis[maxn*15];
     19 struct Num_{
     20     int id;ll dis;
     21     bool operator < (const Num_&a) const{
     22         return a.dis<dis;
     23     }
     24 }e;
     25 priority_queue<Num_>pri;
     26 struct Edge{ int to,nx; ll dis; }edge[maxn*40];
     27 inline void Add_edge(int from,int to,int dis){
     28     edge[++num_edge].nx=edge_head[from];
     29     edge[num_edge].to=to;
     30     edge[num_edge].dis=dis;
     31     edge_head[from]=num_edge;
     32     return;
     33 }
     34 void Build(int x,int l,int r){
     35     if(l==r){
     36         tr[x][0]=tr[x][1]=l;
     37         return;
     38     }
     39     int m=(l+r)>>1;
     40     tr[x][0]=++cnt; tr[x][1]=++cnt;
     41     Build(x<<1,l,m); Build(x<<1|1,m+1,r);
     42     Add_edge(tr[x][0],tr[x<<1][0],0);
     43     Add_edge(tr[x][0],tr[x<<1|1][0],0);
     44     Add_edge(tr[x<<1][1],tr[x][1],0);
     45     Add_edge(tr[x<<1|1][1],tr[x][1],0);
     46     return;
     47 }
     48 void Update(int x,int l,int r,int ql,int qr,int u,int val,int op){
     49     if(ql<=l&&r<=qr){
     50         if(op==0) Add_edge(u,tr[x][0],val);
     51         else Add_edge(tr[x][1],u,val);
     52         return;
     53     }
     54     int m=(l+r)>>1;
     55     if(ql<=m)Update(x<<1,l,m,ql,qr,u,val,op);
     56     if(qr>m)Update(x<<1|1,m+1,r,ql,qr,u,val,op);
     57     return;
     58 }
     59 inline void Dijkstra(int s){
     60     for(int i=1;i<=cnt;i++)Dis[i]=inf;
     61     Dis[s]=0;
     62     e.id=s;e.dis=0;
     63     pri.push(e);
     64     while(!pri.empty()){
     65         int x=(pri.top()).id;
     66         pri.pop();
     67         if(vis[x])continue;
     68         vis[x]=1;
     69         for(int i=edge_head[x];i;i=edge[i].nx){
     70             int y=edge[i].to;
     71             if(Dis[x]+edge[i].dis<Dis[y]){
     72                 Dis[y]=Dis[x]+edge[i].dis;
     73                 e.id=y;e.dis=Dis[y];
     74                 pri.push(e);
     75             }
     76         }
     77     }
     78     return;
     79 }
     80 int main(){
     81     N=rd();Q=rd();S=rd();
     82     cnt=N;
     83     Build(1,1,N);
     84     while(Q--){
     85         o=rd();
     86         if(o==1){
     87             v=rd();u=rd();w=rd();
     88             Add_edge(v,u,w);
     89         }
     90         else {
     91             v=rd();ql=rd();qr=rd();w=rd();
     92             if(o==2)
     93                 Update(1,1,N,ql,qr,v,w,0);
     94             else//o==3
     95                 Update(1,1,N,ql,qr,v,w,1);
     96         }
     97     }
     98     Dijkstra(S);
     99     for(int i=1;i<=N;i++)
    100         if(Dis[i]!=inf)printf("%lld ",Dis[i]);
    101         else printf("-1 ");
    102     return 0;
    103 }
    邻接表建图版
      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<queue>
      5 #define make(a,b) (make_pair(a,b))
      6 #define ll long long
      7 using namespace std;
      8 inline ll rd(){
      9     ll x=0,f=1;char c=getchar();
     10     while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
     11     while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
     12     return f*x;
     13 }
     14 const int maxn=(1e5)+50,maxq=maxn;
     15 const ll inf=1ll<<60;
     16 int N,Q,S,trIn[maxn<<2],trOut[maxn<<2];
     17 int u,v,ql,qr,o,cnt;
     18 bool vis[maxn<<3];
     19 vector<pair<int,ll> >edge[maxn<<3];//to,val
     20 ll w,Dis[maxn<<3];
     21 struct Num_{
     22     ll dis;
     23     int id;
     24     bool operator < (const Num_&a) const {
     25         return a.dis<dis;
     26     }
     27 }b;
     28 priority_queue<Num_>pri;
     29 void Build(int x,int l,int r){
     30     if(l==r){
     31         trIn[x]=l;
     32         trOut[x]=l;
     33         return;
     34     }
     35     int mid=(l+r)>>1;
     36     trIn[x]=++cnt;trOut[x]=++cnt;
     37     Build(x<<1,l,mid);Build(x<<1|1,mid+1,r);
     38     edge[trIn[x]].push_back(make(trIn[x<<1],0));
     39     edge[trIn[x]].push_back(make(trIn[x<<1|1],0));
     40     edge[trOut[x<<1]].push_back(make(trOut[x],0));
     41     edge[trOut[x<<1|1]].push_back(make(trOut[x],0));
     42     return;
     43 }
     44 void Update(int x,int l,int r,int ql,int qr,int u,int val,int o){
     45     if(ql<=l&&r<=qr){
     46         if(o==2)//In
     47             edge[u].push_back(make(trIn[x],val));
     48         else//Out
     49             edge[trOut[x]].push_back(make(u,val));
     50         return;
     51     }
     52     int mid=(l+r)>>1;
     53     if(ql<=mid)Update(x<<1,l,mid,ql,qr,u,val,o);
     54     if(qr>mid)Update(x<<1|1,mid+1,r,ql,qr,u,val,o);
     55     return;
     56 }
     57 inline void Dijkstra(int s){
     58     for(int i=1;i<=cnt;i++)Dis[i]=inf;
     59     Dis[s]=0;
     60     b.dis=0;b.id=s;
     61     pri.push(b);
     62     while(!pri.empty()){
     63         int x=(pri.top()).id;
     64         pri.pop();
     65         if(vis[x])continue;
     66         vis[x]=1;
     67         int toi=edge[x].size();
     68         for(int i=0;i<toi;i++){
     69             int y=edge[x][i].first;
     70             if(Dis[y]>Dis[x]+edge[x][i].second){
     71                 Dis[y]=Dis[x]+edge[x][i].second;
     72                 b.id=y;b.dis=Dis[y];
     73                 pri.push(b);
     74             }
     75         }
     76     }
     77     return;
     78 }
     79 int main(){
     80     N=rd();Q=rd();S=rd();
     81     cnt=N;
     82     Build(1,1,N);
     83     while(Q--){
     84         o=rd();
     85         if(o==1){
     86             v=rd();u=rd();w=rd();
     87             edge[v].push_back(make(u,w));
     88         }
     89         else if(o==2){
     90             v=rd();ql=rd();
     91             qr=rd();w=rd();
     92             Update(1,1,N,ql,qr,v,w,2);
     93         }
     94         else {//o==3
     95             v=rd();ql=rd();
     96             qr=rd();w=rd();
     97             Update(1,1,N,ql,qr,v,w,3);
     98         }
     99     }
    100     Dijkstra(S);
    101     for(int i=1;i<=N;i++){
    102         if(Dis[i]!=inf) printf("%lld ",Dis[i]);
    103         else printf("-1 ");
    104     }
    105     return 0;
    106 }
    Vector建图版

    By:AlenaNuna

  • 相关阅读:
    Java中类的继承
    信号量、PV原语及其应用
    Python-subprocess执行命令并将输出劫持实现实时记录到日志
    Python-logging模块定制格式描述符实现定长日志等级
    Python-logging模块实现同时向控制台和文件打印日志
    SpringBoot学习笔记(二)
    Kubernetes学习日记(四)
    Kubernetes学习日记(三)
    SpringBoot学习笔记(一)
    Kubernetes学习日记(二)
  • 原文地址:https://www.cnblogs.com/AlenaNuna/p/11300895.html
Copyright © 2011-2022 走看看